diff --git a/.optimize-cache.json b/.optimize-cache.json index bc81a830f0..a6251ee92b 100644 --- a/.optimize-cache.json +++ b/.optimize-cache.json @@ -42,6 +42,7 @@ "images/avatars/jesse.png": "99f96274279be20c2bf6c97feeef9f61b7fb8bde6404b4f2472cfd63b44f6cdf", "images/avatars/kushboo.png": "b64531c4b946dfe64c542c7d400a431c8b6634b1bfafda5cd293ba14407a80b6", "images/avatars/laura.png": "608a5ca230d0dbd4fbedac4c9f3b6203f1e70108c3da697d79e2f13a607d7d33", + "images/avatars/levi-van-noort.png": "42aa314246f4adde1a3db59b9e227f6f216fb99888be8e60b50bd3af7a66253c", "images/avatars/luke.png": "d3945fa606673bcef524da2736fa27bc4a4ee75e8b188a80b1e7d511f4def350", "images/avatars/matej.png": "5b456bf1472486f98610cb8f76c3aacc1fa413b8486b5b119639d2dacc700187", "images/avatars/may.png": "b060895e3a13de66ba4834177643fec8ec700a18eaeee56d5d12ad58ff103f7b", @@ -1012,6 +1013,7 @@ "images/blog/sveltekit-starter-sites/template.png": "8d1e7fe52725bff2804d43e38c2cdc06b73d29072ceb25c321e8aa18a3751d00", "images/blog/swift-101/cover.png": "d9ad9fd4e8c4b12216bb6b0c7d1d40c75afa0642aaedb66d89d0dc9a6f85e096", "images/blog/tanstack-start-support-in-appwrite-sites/cover.png": "1e01e95acb829ec3e29c709d4a49e81346d47fe96bc12a0c0e48f209a0d88fd6", + "images/blog/terraform-provider-appwrite/cover.png": "faf8a32b84ed48402fa6a771993fedcd136b024896a1833c0f91a15196d8a393", "images/blog/the-appwrite-network/cloud-regions.png": "bfda330a650bcc4295d1b6bdec9d72287522061ebbbac8b0828d29088fa30563", "images/blog/the-appwrite-network/network-cover-image.png": "b865fc4e14fbcba8e4b68ba5025d5999ac01e40422e18369a9e0649bdd99b2e1", "images/blog/the-appwrite-network/regions-edges-pops.png": "0cf9a1dc9cceafc9be34004396e171b20168ae333efc0d557c8268a91cc83053", @@ -1807,6 +1809,7 @@ "images/integrations/stripe-subscriptions/variables.png": "36d35f5c554e658862d8f8981cf04ee157c2282c97a89282ef91b1346005316f", "images/integrations/stripe-subscriptions/web-platform.png": "4fa7e4ef19d6417f49d651deaf62e158173aec5da2d21e150de679bfc25163b0", "images/integrations/stripe-subscriptions/webhooks.png": "641cc545aa64d137619a7768c553f9aeb30507cd7209cf33bc08f476b95975eb", + "images/integrations/terraform/cover.png": "43b4f901f490adab9f018c600882132192c29092f44154226fc72196e2d5a3fe", "images/integrations/whatsapp-vonage/cover.png": "c445579cca51fcafa1a0717abf51386e1d86a5909951a7a05401b0e77dc506d4", "images/integrations/whatsapp-vonage/demo.png": "34ffa1310f6d01e2c22b0d4473d8f89f4306610d8db1d01f53771da6628023e6", "images/integrations/whatsapp-vonage/settings.png": "57dc4bb24aac093bdd115c60d350de19a14d87fc5ed08d8bf833889a95414570", diff --git a/src/icons/optimized/terraform.svg b/src/icons/optimized/terraform.svg new file mode 100644 index 0000000000..af5548f481 --- /dev/null +++ b/src/icons/optimized/terraform.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/output/_variables.scss b/src/icons/output/_variables.scss index 2a0a56c17d..50a764a4e9 100644 --- a/src/icons/output/_variables.scss +++ b/src/icons/output/_variables.scss @@ -30,39 +30,40 @@ $web-icon-plus: "\ea1d"; $web-icon-check: "\ea1e"; $web-icon-close: "\ea1f"; $web-icon-copy: "\ea20"; -$web-icon-message: "\ea21"; -$web-icon-play: "\ea22"; -$web-icon-remix: "\ea23"; -$web-icon-skills: "\ea24"; -$web-icon-hamburger-menu: "\ea25"; -$web-icon-google: "\ea26"; -$web-icon-rest: "\ea27"; -$web-icon-star: "\ea28"; -$web-icon-mailgun: "\ea29"; -$web-icon-regions: "\ea2a"; -$web-icon-youtube: "\ea2b"; -$web-icon-command: "\ea2c"; -$web-icon-logout-right: "\ea2d"; -$web-icon-tanstack: "\ea2e"; -$web-icon-location: "\ea2f"; -$web-icon-arrow-up: "\ea30"; -$web-icon-linkedin: "\ea31"; -$web-icon-arena: "\ea32"; -$web-icon-twitter: "\ea33"; -$web-icon-customize: "\ea34"; -$web-icon-discord: "\ea35"; -$web-icon-calendar: "\ea36"; -$web-icon-arrow-left: "\ea37"; -$web-icon-sendgrid: "\ea38"; -$web-icon-pop-locations: "\ea39"; -$web-icon-product-hunt: "\ea3a"; -$web-icon-appwrite: "\ea3b"; -$web-icon-arrow-ext-link: "\ea3c"; -$web-icon-logout-left: "\ea3d"; -$web-icon-external-icon: "\ea3e"; -$web-icon-apple: "\ea3f"; -$web-icon-tiktok: "\ea40"; -$web-icon-minus: "\ea41"; -$web-icon-chevron-left: "\ea42"; -$web-icon-light: "\ea43"; -$web-icon-mcp: "\ea44"; +$web-icon-terraform: "\ea21"; +$web-icon-message: "\ea22"; +$web-icon-play: "\ea23"; +$web-icon-remix: "\ea24"; +$web-icon-skills: "\ea25"; +$web-icon-hamburger-menu: "\ea26"; +$web-icon-google: "\ea27"; +$web-icon-rest: "\ea28"; +$web-icon-star: "\ea29"; +$web-icon-mailgun: "\ea2a"; +$web-icon-regions: "\ea2b"; +$web-icon-youtube: "\ea2c"; +$web-icon-command: "\ea2d"; +$web-icon-logout-right: "\ea2e"; +$web-icon-tanstack: "\ea2f"; +$web-icon-location: "\ea30"; +$web-icon-arrow-up: "\ea31"; +$web-icon-linkedin: "\ea32"; +$web-icon-arena: "\ea33"; +$web-icon-twitter: "\ea34"; +$web-icon-customize: "\ea35"; +$web-icon-discord: "\ea36"; +$web-icon-calendar: "\ea37"; +$web-icon-arrow-left: "\ea38"; +$web-icon-sendgrid: "\ea39"; +$web-icon-pop-locations: "\ea3a"; +$web-icon-product-hunt: "\ea3b"; +$web-icon-appwrite: "\ea3c"; +$web-icon-arrow-ext-link: "\ea3d"; +$web-icon-logout-left: "\ea3e"; +$web-icon-external-icon: "\ea3f"; +$web-icon-apple: "\ea40"; +$web-icon-tiktok: "\ea41"; +$web-icon-minus: "\ea42"; +$web-icon-chevron-left: "\ea43"; +$web-icon-light: "\ea44"; +$web-icon-mcp: "\ea45"; diff --git a/src/icons/output/info.json b/src/icons/output/info.json index 49f9c070ed..4ec890db30 100644 --- a/src/icons/output/info.json +++ b/src/icons/output/info.json @@ -191,220 +191,226 @@ "className": "web-icon-copy", "unicode": "" }, - "message": { + "terraform": { "encodedCode": "\\ea21", "prefix": "web-icon", - "className": "web-icon-message", + "className": "web-icon-terraform", "unicode": "" }, - "play": { + "message": { "encodedCode": "\\ea22", "prefix": "web-icon", - "className": "web-icon-play", + "className": "web-icon-message", "unicode": "" }, - "remix": { + "play": { "encodedCode": "\\ea23", "prefix": "web-icon", - "className": "web-icon-remix", + "className": "web-icon-play", "unicode": "" }, - "skills": { + "remix": { "encodedCode": "\\ea24", "prefix": "web-icon", - "className": "web-icon-skills", + "className": "web-icon-remix", "unicode": "" }, - "hamburger-menu": { + "skills": { "encodedCode": "\\ea25", "prefix": "web-icon", - "className": "web-icon-hamburger-menu", + "className": "web-icon-skills", "unicode": "" }, - "google": { + "hamburger-menu": { "encodedCode": "\\ea26", "prefix": "web-icon", - "className": "web-icon-google", + "className": "web-icon-hamburger-menu", "unicode": "" }, - "rest": { + "google": { "encodedCode": "\\ea27", "prefix": "web-icon", - "className": "web-icon-rest", + "className": "web-icon-google", "unicode": "" }, - "star": { + "rest": { "encodedCode": "\\ea28", "prefix": "web-icon", - "className": "web-icon-star", + "className": "web-icon-rest", "unicode": "" }, - "mailgun": { + "star": { "encodedCode": "\\ea29", "prefix": "web-icon", - "className": "web-icon-mailgun", + "className": "web-icon-star", "unicode": "" }, - "regions": { + "mailgun": { "encodedCode": "\\ea2a", "prefix": "web-icon", - "className": "web-icon-regions", + "className": "web-icon-mailgun", "unicode": "" }, - "youtube": { + "regions": { "encodedCode": "\\ea2b", "prefix": "web-icon", - "className": "web-icon-youtube", + "className": "web-icon-regions", "unicode": "" }, - "command": { + "youtube": { "encodedCode": "\\ea2c", "prefix": "web-icon", - "className": "web-icon-command", + "className": "web-icon-youtube", "unicode": "" }, - "logout-right": { + "command": { "encodedCode": "\\ea2d", "prefix": "web-icon", - "className": "web-icon-logout-right", + "className": "web-icon-command", "unicode": "" }, - "tanstack": { + "logout-right": { "encodedCode": "\\ea2e", "prefix": "web-icon", - "className": "web-icon-tanstack", + "className": "web-icon-logout-right", "unicode": "" }, - "location": { + "tanstack": { "encodedCode": "\\ea2f", "prefix": "web-icon", - "className": "web-icon-location", + "className": "web-icon-tanstack", "unicode": "" }, - "arrow-up": { + "location": { "encodedCode": "\\ea30", "prefix": "web-icon", - "className": "web-icon-arrow-up", + "className": "web-icon-location", "unicode": "" }, - "linkedin": { + "arrow-up": { "encodedCode": "\\ea31", "prefix": "web-icon", - "className": "web-icon-linkedin", + "className": "web-icon-arrow-up", "unicode": "" }, - "arena": { + "linkedin": { "encodedCode": "\\ea32", "prefix": "web-icon", - "className": "web-icon-arena", + "className": "web-icon-linkedin", "unicode": "" }, - "twitter": { + "arena": { "encodedCode": "\\ea33", "prefix": "web-icon", - "className": "web-icon-twitter", + "className": "web-icon-arena", "unicode": "" }, - "customize": { + "twitter": { "encodedCode": "\\ea34", "prefix": "web-icon", - "className": "web-icon-customize", + "className": "web-icon-twitter", "unicode": "" }, - "discord": { + "customize": { "encodedCode": "\\ea35", "prefix": "web-icon", - "className": "web-icon-discord", + "className": "web-icon-customize", "unicode": "" }, - "calendar": { + "discord": { "encodedCode": "\\ea36", "prefix": "web-icon", - "className": "web-icon-calendar", + "className": "web-icon-discord", "unicode": "" }, - "arrow-left": { + "calendar": { "encodedCode": "\\ea37", "prefix": "web-icon", - "className": "web-icon-arrow-left", + "className": "web-icon-calendar", "unicode": "" }, - "sendgrid": { + "arrow-left": { "encodedCode": "\\ea38", "prefix": "web-icon", - "className": "web-icon-sendgrid", + "className": "web-icon-arrow-left", "unicode": "" }, - "pop-locations": { + "sendgrid": { "encodedCode": "\\ea39", "prefix": "web-icon", - "className": "web-icon-pop-locations", + "className": "web-icon-sendgrid", "unicode": "" }, - "product-hunt": { + "pop-locations": { "encodedCode": "\\ea3a", "prefix": "web-icon", - "className": "web-icon-product-hunt", + "className": "web-icon-pop-locations", "unicode": "" }, - "appwrite": { + "product-hunt": { "encodedCode": "\\ea3b", "prefix": "web-icon", - "className": "web-icon-appwrite", + "className": "web-icon-product-hunt", "unicode": "" }, - "arrow-ext-link": { + "appwrite": { "encodedCode": "\\ea3c", "prefix": "web-icon", - "className": "web-icon-arrow-ext-link", + "className": "web-icon-appwrite", "unicode": "" }, - "logout-left": { + "arrow-ext-link": { "encodedCode": "\\ea3d", "prefix": "web-icon", - "className": "web-icon-logout-left", + "className": "web-icon-arrow-ext-link", "unicode": "" }, - "external-icon": { + "logout-left": { "encodedCode": "\\ea3e", "prefix": "web-icon", - "className": "web-icon-external-icon", + "className": "web-icon-logout-left", "unicode": "" }, - "apple": { + "external-icon": { "encodedCode": "\\ea3f", "prefix": "web-icon", - "className": "web-icon-apple", + "className": "web-icon-external-icon", "unicode": "" }, - "tiktok": { + "apple": { "encodedCode": "\\ea40", "prefix": "web-icon", - "className": "web-icon-tiktok", + "className": "web-icon-apple", "unicode": "" }, - "minus": { + "tiktok": { "encodedCode": "\\ea41", "prefix": "web-icon", - "className": "web-icon-minus", + "className": "web-icon-tiktok", "unicode": "" }, - "chevron-left": { + "minus": { "encodedCode": "\\ea42", "prefix": "web-icon", - "className": "web-icon-chevron-left", + "className": "web-icon-minus", "unicode": "" }, - "light": { + "chevron-left": { "encodedCode": "\\ea43", "prefix": "web-icon", - "className": "web-icon-light", + "className": "web-icon-chevron-left", "unicode": "" }, - "mcp": { + "light": { "encodedCode": "\\ea44", "prefix": "web-icon", - "className": "web-icon-mcp", + "className": "web-icon-light", "unicode": "" + }, + "mcp": { + "encodedCode": "\\ea45", + "prefix": "web-icon", + "className": "web-icon-mcp", + "unicode": "" } } diff --git a/src/icons/output/web-icon.css b/src/icons/output/web-icon.css index 914702986b..d7bd982312 100644 --- a/src/icons/output/web-icon.css +++ b/src/icons/output/web-icon.css @@ -116,111 +116,114 @@ .web-icon-copy:before { content: '\ea20'; } -.web-icon-message:before { +.web-icon-terraform:before { content: '\ea21'; } -.web-icon-play:before { +.web-icon-message:before { content: '\ea22'; } -.web-icon-remix:before { +.web-icon-play:before { content: '\ea23'; } -.web-icon-skills:before { +.web-icon-remix:before { content: '\ea24'; } -.web-icon-hamburger-menu:before { +.web-icon-skills:before { content: '\ea25'; } -.web-icon-google:before { +.web-icon-hamburger-menu:before { content: '\ea26'; } -.web-icon-rest:before { +.web-icon-google:before { content: '\ea27'; } -.web-icon-star:before { +.web-icon-rest:before { content: '\ea28'; } -.web-icon-mailgun:before { +.web-icon-star:before { content: '\ea29'; } -.web-icon-regions:before { +.web-icon-mailgun:before { content: '\ea2a'; } -.web-icon-youtube:before { +.web-icon-regions:before { content: '\ea2b'; } -.web-icon-command:before { +.web-icon-youtube:before { content: '\ea2c'; } -.web-icon-logout-right:before { +.web-icon-command:before { content: '\ea2d'; } -.web-icon-tanstack:before { +.web-icon-logout-right:before { content: '\ea2e'; } -.web-icon-location:before { +.web-icon-tanstack:before { content: '\ea2f'; } -.web-icon-arrow-up:before { +.web-icon-location:before { content: '\ea30'; } -.web-icon-linkedin:before { +.web-icon-arrow-up:before { content: '\ea31'; } -.web-icon-arena:before { +.web-icon-linkedin:before { content: '\ea32'; } -.web-icon-twitter:before { +.web-icon-arena:before { content: '\ea33'; } -.web-icon-customize:before { +.web-icon-twitter:before { content: '\ea34'; } -.web-icon-discord:before { +.web-icon-customize:before { content: '\ea35'; } -.web-icon-calendar:before { +.web-icon-discord:before { content: '\ea36'; } -.web-icon-arrow-left:before { +.web-icon-calendar:before { content: '\ea37'; } -.web-icon-sendgrid:before { +.web-icon-arrow-left:before { content: '\ea38'; } -.web-icon-pop-locations:before { +.web-icon-sendgrid:before { content: '\ea39'; } -.web-icon-product-hunt:before { +.web-icon-pop-locations:before { content: '\ea3a'; } -.web-icon-appwrite:before { +.web-icon-product-hunt:before { content: '\ea3b'; } -.web-icon-arrow-ext-link:before { +.web-icon-appwrite:before { content: '\ea3c'; } -.web-icon-logout-left:before { +.web-icon-arrow-ext-link:before { content: '\ea3d'; } -.web-icon-external-icon:before { +.web-icon-logout-left:before { content: '\ea3e'; } -.web-icon-apple:before { +.web-icon-external-icon:before { content: '\ea3f'; } -.web-icon-tiktok:before { +.web-icon-apple:before { content: '\ea40'; } -.web-icon-minus:before { +.web-icon-tiktok:before { content: '\ea41'; } -.web-icon-chevron-left:before { +.web-icon-minus:before { content: '\ea42'; } -.web-icon-light:before { +.web-icon-chevron-left:before { content: '\ea43'; } -.web-icon-mcp:before { +.web-icon-light:before { content: '\ea44'; } +.web-icon-mcp:before { + content: '\ea45'; +} diff --git a/src/icons/output/web-icon.eot b/src/icons/output/web-icon.eot index 428dc6f998..8f15a83846 100644 Binary files a/src/icons/output/web-icon.eot and b/src/icons/output/web-icon.eot differ diff --git a/src/icons/output/web-icon.scss b/src/icons/output/web-icon.scss index 0913ae9ad4..cd8eed8dce 100644 --- a/src/icons/output/web-icon.scss +++ b/src/icons/output/web-icon.scss @@ -48,42 +48,43 @@ .web-icon-check:before { content: "\ea1e"; } .web-icon-close:before { content: "\ea1f"; } .web-icon-copy:before { content: "\ea20"; } -.web-icon-message:before { content: "\ea21"; } -.web-icon-play:before { content: "\ea22"; } -.web-icon-remix:before { content: "\ea23"; } -.web-icon-skills:before { content: "\ea24"; } -.web-icon-hamburger-menu:before { content: "\ea25"; } -.web-icon-google:before { content: "\ea26"; } -.web-icon-rest:before { content: "\ea27"; } -.web-icon-star:before { content: "\ea28"; } -.web-icon-mailgun:before { content: "\ea29"; } -.web-icon-regions:before { content: "\ea2a"; } -.web-icon-youtube:before { content: "\ea2b"; } -.web-icon-command:before { content: "\ea2c"; } -.web-icon-logout-right:before { content: "\ea2d"; } -.web-icon-tanstack:before { content: "\ea2e"; } -.web-icon-location:before { content: "\ea2f"; } -.web-icon-arrow-up:before { content: "\ea30"; } -.web-icon-linkedin:before { content: "\ea31"; } -.web-icon-arena:before { content: "\ea32"; } -.web-icon-twitter:before { content: "\ea33"; } -.web-icon-customize:before { content: "\ea34"; } -.web-icon-discord:before { content: "\ea35"; } -.web-icon-calendar:before { content: "\ea36"; } -.web-icon-arrow-left:before { content: "\ea37"; } -.web-icon-sendgrid:before { content: "\ea38"; } -.web-icon-pop-locations:before { content: "\ea39"; } -.web-icon-product-hunt:before { content: "\ea3a"; } -.web-icon-appwrite:before { content: "\ea3b"; } -.web-icon-arrow-ext-link:before { content: "\ea3c"; } -.web-icon-logout-left:before { content: "\ea3d"; } -.web-icon-external-icon:before { content: "\ea3e"; } -.web-icon-apple:before { content: "\ea3f"; } -.web-icon-tiktok:before { content: "\ea40"; } -.web-icon-minus:before { content: "\ea41"; } -.web-icon-chevron-left:before { content: "\ea42"; } -.web-icon-light:before { content: "\ea43"; } -.web-icon-mcp:before { content: "\ea44"; } +.web-icon-terraform:before { content: "\ea21"; } +.web-icon-message:before { content: "\ea22"; } +.web-icon-play:before { content: "\ea23"; } +.web-icon-remix:before { content: "\ea24"; } +.web-icon-skills:before { content: "\ea25"; } +.web-icon-hamburger-menu:before { content: "\ea26"; } +.web-icon-google:before { content: "\ea27"; } +.web-icon-rest:before { content: "\ea28"; } +.web-icon-star:before { content: "\ea29"; } +.web-icon-mailgun:before { content: "\ea2a"; } +.web-icon-regions:before { content: "\ea2b"; } +.web-icon-youtube:before { content: "\ea2c"; } +.web-icon-command:before { content: "\ea2d"; } +.web-icon-logout-right:before { content: "\ea2e"; } +.web-icon-tanstack:before { content: "\ea2f"; } +.web-icon-location:before { content: "\ea30"; } +.web-icon-arrow-up:before { content: "\ea31"; } +.web-icon-linkedin:before { content: "\ea32"; } +.web-icon-arena:before { content: "\ea33"; } +.web-icon-twitter:before { content: "\ea34"; } +.web-icon-customize:before { content: "\ea35"; } +.web-icon-discord:before { content: "\ea36"; } +.web-icon-calendar:before { content: "\ea37"; } +.web-icon-arrow-left:before { content: "\ea38"; } +.web-icon-sendgrid:before { content: "\ea39"; } +.web-icon-pop-locations:before { content: "\ea3a"; } +.web-icon-product-hunt:before { content: "\ea3b"; } +.web-icon-appwrite:before { content: "\ea3c"; } +.web-icon-arrow-ext-link:before { content: "\ea3d"; } +.web-icon-logout-left:before { content: "\ea3e"; } +.web-icon-external-icon:before { content: "\ea3f"; } +.web-icon-apple:before { content: "\ea40"; } +.web-icon-tiktok:before { content: "\ea41"; } +.web-icon-minus:before { content: "\ea42"; } +.web-icon-chevron-left:before { content: "\ea43"; } +.web-icon-light:before { content: "\ea44"; } +.web-icon-mcp:before { content: "\ea45"; } $web-icon-search: "\ea01"; $web-icon-arrow-down: "\ea02"; @@ -117,39 +118,40 @@ $web-icon-plus: "\ea1d"; $web-icon-check: "\ea1e"; $web-icon-close: "\ea1f"; $web-icon-copy: "\ea20"; -$web-icon-message: "\ea21"; -$web-icon-play: "\ea22"; -$web-icon-remix: "\ea23"; -$web-icon-skills: "\ea24"; -$web-icon-hamburger-menu: "\ea25"; -$web-icon-google: "\ea26"; -$web-icon-rest: "\ea27"; -$web-icon-star: "\ea28"; -$web-icon-mailgun: "\ea29"; -$web-icon-regions: "\ea2a"; -$web-icon-youtube: "\ea2b"; -$web-icon-command: "\ea2c"; -$web-icon-logout-right: "\ea2d"; -$web-icon-tanstack: "\ea2e"; -$web-icon-location: "\ea2f"; -$web-icon-arrow-up: "\ea30"; -$web-icon-linkedin: "\ea31"; -$web-icon-arena: "\ea32"; -$web-icon-twitter: "\ea33"; -$web-icon-customize: "\ea34"; -$web-icon-discord: "\ea35"; -$web-icon-calendar: "\ea36"; -$web-icon-arrow-left: "\ea37"; -$web-icon-sendgrid: "\ea38"; -$web-icon-pop-locations: "\ea39"; -$web-icon-product-hunt: "\ea3a"; -$web-icon-appwrite: "\ea3b"; -$web-icon-arrow-ext-link: "\ea3c"; -$web-icon-logout-left: "\ea3d"; -$web-icon-external-icon: "\ea3e"; -$web-icon-apple: "\ea3f"; -$web-icon-tiktok: "\ea40"; -$web-icon-minus: "\ea41"; -$web-icon-chevron-left: "\ea42"; -$web-icon-light: "\ea43"; -$web-icon-mcp: "\ea44"; +$web-icon-terraform: "\ea21"; +$web-icon-message: "\ea22"; +$web-icon-play: "\ea23"; +$web-icon-remix: "\ea24"; +$web-icon-skills: "\ea25"; +$web-icon-hamburger-menu: "\ea26"; +$web-icon-google: "\ea27"; +$web-icon-rest: "\ea28"; +$web-icon-star: "\ea29"; +$web-icon-mailgun: "\ea2a"; +$web-icon-regions: "\ea2b"; +$web-icon-youtube: "\ea2c"; +$web-icon-command: "\ea2d"; +$web-icon-logout-right: "\ea2e"; +$web-icon-tanstack: "\ea2f"; +$web-icon-location: "\ea30"; +$web-icon-arrow-up: "\ea31"; +$web-icon-linkedin: "\ea32"; +$web-icon-arena: "\ea33"; +$web-icon-twitter: "\ea34"; +$web-icon-customize: "\ea35"; +$web-icon-discord: "\ea36"; +$web-icon-calendar: "\ea37"; +$web-icon-arrow-left: "\ea38"; +$web-icon-sendgrid: "\ea39"; +$web-icon-pop-locations: "\ea3a"; +$web-icon-product-hunt: "\ea3b"; +$web-icon-appwrite: "\ea3c"; +$web-icon-arrow-ext-link: "\ea3d"; +$web-icon-logout-left: "\ea3e"; +$web-icon-external-icon: "\ea3f"; +$web-icon-apple: "\ea40"; +$web-icon-tiktok: "\ea41"; +$web-icon-minus: "\ea42"; +$web-icon-chevron-left: "\ea43"; +$web-icon-light: "\ea44"; +$web-icon-mcp: "\ea45"; diff --git a/src/icons/output/web-icon.svg b/src/icons/output/web-icon.svg index d8dd9ef6d6..f0bd17fdd9 100644 --- a/src/icons/output/web-icon.svg +++ b/src/icons/output/web-icon.svg @@ -103,113 +103,116 @@ - + diff --git a/src/icons/output/web-icon.symbol.svg b/src/icons/output/web-icon.symbol.svg index 88d28b1b88..a2f40e8c41 100644 --- a/src/icons/output/web-icon.symbol.svg +++ b/src/icons/output/web-icon.symbol.svg @@ -3,4 +3,4 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/icons/output/web-icon.ttf b/src/icons/output/web-icon.ttf index f2ae1b364d..36ed35b0b3 100644 Binary files a/src/icons/output/web-icon.ttf and b/src/icons/output/web-icon.ttf differ diff --git a/src/icons/output/web-icon.woff b/src/icons/output/web-icon.woff index b82ea54832..59520e1e38 100644 Binary files a/src/icons/output/web-icon.woff and b/src/icons/output/web-icon.woff differ diff --git a/src/icons/output/web-icon.woff2 b/src/icons/output/web-icon.woff2 index 96501b8097..8901f4d07a 100644 Binary files a/src/icons/output/web-icon.woff2 and b/src/icons/output/web-icon.woff2 differ diff --git a/src/icons/svg/terraform.svg b/src/icons/svg/terraform.svg new file mode 100644 index 0000000000..2158c2ea5b --- /dev/null +++ b/src/icons/svg/terraform.svg @@ -0,0 +1,16 @@ + + + + + + + diff --git a/src/lib/components/ui/icon/sprite/sprite.svelte b/src/lib/components/ui/icon/sprite/sprite.svelte index b5628b191e..269fd84578 100644 --- a/src/lib/components/ui/icon/sprite/sprite.svelte +++ b/src/lib/components/ui/icon/sprite/sprite.svelte @@ -264,6 +264,14 @@ fill-rule="evenodd" > + + + { }); }); +/** HashiCorp Configuration Language (Terraform); core highlight.js has no HCL grammar */ +hljs.registerAliases(['hcl', 'terraform', 'tf'], { languageName: 'ini' }); + export type Language = keyof typeof languages | Platform; type Args = { diff --git a/src/redirects.json b/src/redirects.json index 954da7a415..b763ed84e7 100644 --- a/src/redirects.json +++ b/src/redirects.json @@ -716,6 +716,10 @@ "link": "/docs/tooling/command-line/collections", "redirect": "/docs/tooling/command-line/tables" }, + { + "link": "/docs/tooling/terraform/databases", + "redirect": "/docs/tooling/terraform/resources/databases" + }, { "link": "/docs/tooling/mcp/mcp-for-docs", "redirect": "/docs/tooling/mcp/docs" diff --git a/src/routes/blog/author/levi-van-noort/+page.markdoc b/src/routes/blog/author/levi-van-noort/+page.markdoc new file mode 100644 index 0000000000..361f58bfee --- /dev/null +++ b/src/routes/blog/author/levi-van-noort/+page.markdoc @@ -0,0 +1,10 @@ +--- +layout: author +slug: levi-van-noort +name: Levi van Noort +role: Platform Engineer +bio: Coding on the thin line between applications, cloud, and servers - where the stack gets blurry and the fun starts. +avatar: /images/avatars/levi-van-noort.png +twitter: https://x.com/vannoort_levi +github: https://github.com/levivannoort +--- diff --git a/src/routes/blog/post/introducing-terraform-provider-for-appwrite/+page.markdoc b/src/routes/blog/post/introducing-terraform-provider-for-appwrite/+page.markdoc new file mode 100644 index 0000000000..9f56800873 --- /dev/null +++ b/src/routes/blog/post/introducing-terraform-provider-for-appwrite/+page.markdoc @@ -0,0 +1,121 @@ +--- +layout: post +title: "Introducing Terraform support for Appwrite projects" +description: "The official appwrite/appwrite Terraform provider brings your entire Appwrite project into HashiCorp Configuration Language (HCL): TablesDB, Storage, Functions, Sites, Auth, Messaging, webhooks, backups, and more, with Registry docs, imports, and guides for Cloud and self-hosted Community Edition." +date: 2026-04-19 +cover: /images/blog/terraform-provider-appwrite/cover.png +timeToRead: 10 +author: levi-van-noort +category: product, announcement +featured: false +--- + +If you already treat infrastructure as code elsewhere, Appwrite **project configuration** was the odd layer out: databases, tables, storage buckets, functions, and sites were easy to tweak in the Console, with the CLI, or in `appwrite.json`, and hard to keep identical across staging, production, and extra regions. That is operational drift with a familiar fix - declare the same resources in HashiCorp Configuration Language (HCL), store the Terraform **state** next to your other tooling, and let `plan` / `apply` (or your CI wrapper) do the talking. + +The **official Terraform provider** is now published as [`appwrite/appwrite`](https://registry.terraform.io/providers/appwrite/appwrite/latest) on the HashiCorp Terraform Registry. It manages **project** resources over the Appwrite API: **TablesDB**, **Storage**, **Functions**, **Sites**, **Auth**, **Messaging**, **webhooks**, and **backup policies**. It does **not** install or operate the Appwrite **instance** itself - for that, stay with [self-hosting](/docs/advanced/self-hosting) and your existing deployment story. + +# Why we built it this way + +We set out to make Terraform **cross-cutting** across Appwrite **project** configuration - not a databases-only path you abandon when you work on Functions, Sites, or the next surface area. The provider maps **most** of what you manage at the project layer through the API, so one IaC story covers those capabilities instead of a tool that stops at schemas. + +**Cross-project** mattered too: the same workflow is meant to work **across** Appwrite projects and environments when you need aligned baselines, not only inside a single stack or a single product silo. + +We also wanted it **open by design**. Use it for familiar patterns - parity between environments, `plan` / `apply` in CI, imports from existing projects - or compose resources in ways that fit **your** architecture when you need something less conventional. The point is full freedom to stay traditional or get creative; Terraform is the shared layer, not a rigid template you have to follow. + +# What is in scope + +The provider maps Appwrite project resources to Terraform resources the way you would expect if you have used the platform before. **TablesDB** is the deepest surface: databases, tables, columns, indexes, and rows so you can declare schemas and seed data in HCL. **Storage** covers buckets and file uploads (`appwrite_storage_bucket`, `appwrite_storage_file`). **Functions** and **Sites** let you define serverless functions (with runtimes, schedules, event triggers, and environment variables) and hosted frontends (with framework presets for Next.js, Nuxt, Astro, SvelteKit, and others) right alongside the backend resources they depend on. **Auth** resources manage users and teams (`appwrite_auth_user`, `appwrite_auth_team`). **Messaging** handles providers, topics, and subscribers. Dedicated resources for **webhooks** (`appwrite_webhook`) and **backup policies** (`appwrite_backup_policy`) round out the set. An **`appwrite_tablesdb` data source** looks up an existing database by ID when another resource needs a stable reference. + +Authentication follows the same model as any other automation: your Appwrite **API endpoint**, a **project API key** with the right scopes, and (on Community Edition or dev clusters) whatever TLS settings you already use - the [configuration guide](/docs/tooling/terraform/provider) documents `endpoint`, `project_id`, `api_key`, and `self_signed` so you can mirror how CI talks to Appwrite today. + +# What a basic flow looks like + +End to end, Terraform does what you expect: pin the provider, pass credentials, declare resources, then run `terraform init`, `terraform plan`, and `terraform apply` when you like the diff. The snippets below are intentionally small so you can see the shape before you open the full guides. + +**Provider and configuration.** Declare `appwrite/appwrite`, then point the provider at Appwrite Cloud (swap `` for your [region](/docs/products/network/regions) subdomain). On Community Edition, set `endpoint` to your instance URL and use `self_signed` when you need it - the [Configuration](/docs/tooling/terraform/provider) page has the exact pattern. + +```hcl +terraform { + required_providers { + appwrite = { + source = "appwrite/appwrite" + version = "~> 1.0" + } + } +} + +provider "appwrite" { + endpoint = "https://.cloud.appwrite.io/v1" + project_id = "project-id" + api_key = "api-key" +} +``` + +**A database and table.** A `appwrite_tablesdb` resource creates a database, and `appwrite_tablesdb_table` adds a table inside it. + +```hcl +resource "appwrite_tablesdb" "main" { + name = "main" +} + +resource "appwrite_tablesdb_table" "users" { + database_id = appwrite_tablesdb.main.id + name = "users" +} +``` + +**A storage bucket.** Buckets follow the same pattern - declare the resource and configure the options you need. + +```hcl +resource "appwrite_storage_bucket" "images" { + name = "images" + maximum_file_size = 10485760 + allowed_file_extensions = ["jpg", "png", "webp", "gif"] + compression = "gzip" +} +``` + +**A serverless function.** Declare the runtime, wire up event triggers, and set environment variables - all in HCL. + +```hcl +resource "appwrite_function" "on_signup" { + name = "on-signup" + runtime = "node-22" + entrypoint = "index.js" + commands = "npm install" + events = ["users.*.create"] + timeout = 30 +} + +resource "appwrite_function_variable" "api_url" { + function_id = appwrite_function.on_signup.id + key = "API_URL" + value = "https://api.example.com" +} +``` + +**A hosted site.** Pick a framework preset and configure the build pipeline. + +```hcl +resource "appwrite_site" "dashboard" { + name = "dashboard" + framework = "nextjs" + build_runtime = "node-22" + install_command = "npm install" + build_command = "npm run build" +} +``` + +From there you layer columns, indexes, rows, files, messaging resources, webhooks, backup policies, and data sources as needed - start from the [Terraform provider overview](/docs/tooling/terraform) and the guides for [Databases](/docs/tooling/terraform/resources/databases), [Storage](/docs/tooling/terraform/resources/storage), [Functions](/docs/tooling/terraform/resources/functions), [Sites](/docs/tooling/terraform/resources/sites), [Auth](/docs/tooling/terraform/resources/auth), [Messaging](/docs/tooling/terraform/resources/messaging), [Webhooks](/docs/tooling/terraform/resources/webhooks), and [Backups](/docs/tooling/terraform/resources/backups). + +# How Terraform fits + +You are not replacing the Console for debugging or the SDKs for application logic. You are giving **project-level config** a path through code review, pinned **`required_providers`** versions, and repeatable applies - the same contract you use when someone opens a PR against VPC rules or a managed database. + +In practice that usually means: preview changes with `terraform plan` before they hit a shared environment; attach plans to tickets or merge requests; and **import** resources that predate the Terraform rollout instead of recreating them by hand. The generated documentation on the [**Terraform Registry**](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs) is the source of truth for arguments, attributes, and **import** syntax per resource. + +# Where to go next + +Our [**Terraform provider**](/docs/tooling/terraform) docs list every resource area and link to [**Configuration**](/docs/tooling/terraform/provider) (`required_providers`, environment variables, optional per-resource `project_id`), resource guides for [**Databases**](/docs/tooling/terraform/resources/databases) (including the **`appwrite_tablesdb` data source** for lookups), [**Storage**](/docs/tooling/terraform/resources/storage), [**Messaging**](/docs/tooling/terraform/resources/messaging), [**Auth**](/docs/tooling/terraform/resources/auth), [**Functions**](/docs/tooling/terraform/resources/functions), [**Sites**](/docs/tooling/terraform/resources/sites), [**Webhooks**](/docs/tooling/terraform/resources/webhooks), and [**Backups**](/docs/tooling/terraform/resources/backups). + +The implementation is open source at [`appwrite/terraform-provider-appwrite`](https://github.com/appwrite/terraform-provider-appwrite) for issues, feature discussion, and contributions. The [**Integrations**](/integrations) catalog also lists [**Terraform provider for Appwrite**](/integrations/terraform-provider) next to the rest of the ecosystem. This release is summarized in the [changelog](/changelog/entry/2026-04-19). The [Registry listing](https://registry.terraform.io/providers/appwrite/appwrite/latest) tracks the latest published **provider version** and generated schema. diff --git a/src/routes/changelog/(entries)/2026-04-19.markdoc b/src/routes/changelog/(entries)/2026-04-19.markdoc new file mode 100644 index 0000000000..89510282e5 --- /dev/null +++ b/src/routes/changelog/(entries)/2026-04-19.markdoc @@ -0,0 +1,14 @@ +--- +layout: changelog +title: "Terraform provider for Appwrite" +date: 2026-04-19 +cover: /images/blog/terraform-provider-appwrite/cover.png +--- + +You can now learn how to manage Appwrite **project configuration as code** with the official [**Terraform provider**](https://registry.terraform.io/providers/appwrite/appwrite/latest) directly in our documentation. Define TablesDB resources, storage buckets and files, Auth users and teams, Functions and Sites, messaging providers, topics, subscribers, webhooks, backup policies, and more in `.tf` files, keep changes in version control, and apply the same setup across staging and production with less manual work in the Console. + +The new [**Terraform provider**](/docs/tooling/terraform) section links to the [Terraform Registry](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs) for full generated schemas and walks through configuration for Appwrite Cloud and Community Edition. We also added a [**Terraform provider**](/integrations/terraform-provider) entry in the integrations catalog. + +{% arrow_link href="/docs/tooling/terraform" %} +Open the Terraform provider docs +{% /arrow_link %} diff --git a/src/routes/docs/Sidebar.svelte b/src/routes/docs/Sidebar.svelte index e700a6afb7..bdd5b3afaf 100644 --- a/src/routes/docs/Sidebar.svelte +++ b/src/routes/docs/Sidebar.svelte @@ -137,6 +137,12 @@ icon: 'icon-terminal', isParent: true }, + { + label: 'Terraform provider', + href: '/docs/tooling/terraform', + icon: 'web-icon-terraform', + isParent: true + }, { label: 'Command Center', href: '/docs/tooling/command-center', diff --git a/src/routes/docs/tooling/terraform/+layout.svelte b/src/routes/docs/tooling/terraform/+layout.svelte new file mode 100644 index 0000000000..31f1751636 --- /dev/null +++ b/src/routes/docs/tooling/terraform/+layout.svelte @@ -0,0 +1,67 @@ + + + + + + diff --git a/src/routes/docs/tooling/terraform/+page.markdoc b/src/routes/docs/tooling/terraform/+page.markdoc new file mode 100644 index 0000000000..b9a0e5269b --- /dev/null +++ b/src/routes/docs/tooling/terraform/+page.markdoc @@ -0,0 +1,90 @@ +--- +layout: article +title: Terraform provider +description: Manage Appwrite infrastructure as code with the official Terraform provider. Works with Appwrite Cloud and Community Edition. +--- + +The [Terraform provider for Appwrite](https://github.com/appwrite/terraform-provider-appwrite) lets you declare **TablesDB** (databases, tables, columns, indexes, rows), **Storage** (buckets and files), **Auth** (users and teams), **Functions** (functions and variables), **Sites** (sites and variables), **Messaging** (providers, topics, subscribers), **webhooks**, **backup policies**, and more in `.tf` files, and apply those changes through [HashiCorp Terraform](https://www.terraform.io/). It is the official way to automate Appwrite project configuration alongside the rest of your stack. + +# Resources and data sources {% #resources-and-data-sources %} + +Resource types use the `appwrite_` prefix and match the [Terraform Registry](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs) documentation. + +| Area | Resources | +|------|-----------| +| TablesDB | `appwrite_tablesdb`, `appwrite_tablesdb_table`, `appwrite_tablesdb_column`, `appwrite_tablesdb_index`, `appwrite_tablesdb_row` | +| Storage | `appwrite_storage_bucket`, `appwrite_storage_file` | +| Auth | `appwrite_auth_user`, `appwrite_auth_team` | +| Functions | `appwrite_function`, `appwrite_function_variable` | +| Sites | `appwrite_site`, `appwrite_site_variable` | +| Messaging | `appwrite_messaging_provider`, `appwrite_messaging_topic`, `appwrite_messaging_subscriber` | +| Webhooks | `appwrite_webhook` | +| Backups | `appwrite_backup_policy` | + +| Kind | Name | Description | +|------|------|-------------| +| Data source | `appwrite_tablesdb` | Look up a database by ID | + +{% info title="Looking for self-hosting?" %} +This section is about **Appwrite resources inside a project** (for example databases and tables) using Terraform. If you want to install or operate the Appwrite server itself (Docker, configuration, TLS, scaling), go to the [self-hosting documentation](/docs/advanced/self-hosting) instead. +{% /info %} + +# What is Terraform? {% #what-is-terraform %} + +[Terraform](https://www.terraform.io/) is an infrastructure-as-code tool. You write **configuration** in a declarative language (HCL) that describes what should exist; Terraform figures out **how** to create or update it. + +If you are new to the idea: + +- **Provider** - A plugin that teaches Terraform how to talk to a specific API (here, Appwrite). +- **Resource** - Something Terraform should create and manage (for example an Appwrite database or table). +- **State** - Terraform remembers what it already created so the next run can update or destroy only what changed. +- **Plan / apply** - You run `terraform plan` to preview changes, then `terraform apply` to execute them. + +You still use the [Appwrite Console](https://cloud.appwrite.io) and SDKs for day-to-day app development; the provider is for **repeatable, version-controlled** setup of project resources across environments. + +# Official repository and registry {% #official-repository-and-registry %} + +Source code, issues, and contribution guidelines: + +{% cards %} +{% cards_item href="https://github.com/appwrite/terraform-provider-appwrite" title="GitHub" icon="web-icon-github" %} +`appwrite/terraform-provider-appwrite` - source and issues. +{% /cards_item %} +{% cards_item href="https://registry.terraform.io/providers/appwrite/appwrite/latest/docs" title="Terraform Registry" icon="web-icon-terraform" %} +`appwrite/appwrite` - install, versions, generated schemas. +{% /cards_item %} +{% /cards %} + +The provider works with **Appwrite Cloud** and **Community Edition** (self-hosted Appwrite). You point it at your API endpoint and authenticate with a project API key. + +# Next steps {% #next-steps %} + +{% cards %} +{% cards_item href="/docs/tooling/terraform/provider" title="Configuration" %} +Install the provider, set endpoints, environment variables, and optional per-resource `project_id`. +{% /cards_item %} +{% cards_item href="/docs/tooling/terraform/resources/databases" title="Databases" %} +TablesDB: databases, tables, columns, indexes, and rows. +{% /cards_item %} +{% cards_item href="/docs/tooling/terraform/resources/storage" title="Storage" %} +Buckets and uploaded files. +{% /cards_item %} +{% cards_item href="/docs/tooling/terraform/resources/messaging" title="Messaging" %} +Providers, topics, and subscribers. +{% /cards_item %} +{% cards_item href="/docs/tooling/terraform/resources/auth" title="Auth" %} +Users and teams. +{% /cards_item %} +{% cards_item href="/docs/tooling/terraform/resources/functions" title="Functions" %} +Functions and environment variables. +{% /cards_item %} +{% cards_item href="/docs/tooling/terraform/resources/sites" title="Sites" %} +Sites and site variables. +{% /cards_item %} +{% cards_item href="/docs/tooling/terraform/resources/webhooks" title="Webhooks" %} +Event delivery to your HTTP endpoints. +{% /cards_item %} +{% cards_item href="/docs/tooling/terraform/resources/backups" title="Backups" %} +Backup policies where supported. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/tooling/terraform/provider/+page.markdoc b/src/routes/docs/tooling/terraform/provider/+page.markdoc new file mode 100644 index 0000000000..96b22a7fb2 --- /dev/null +++ b/src/routes/docs/tooling/terraform/provider/+page.markdoc @@ -0,0 +1,81 @@ +--- +layout: article +title: Configuration +description: Configure the Appwrite Terraform provider for Cloud or Community Edition using endpoints, API keys, and optional environment variables. +--- + +The Appwrite provider is published as `appwrite/appwrite` on the [Terraform Registry](https://registry.terraform.io/providers/appwrite/appwrite/latest). The registry hosts **generated reference docs** for the provider and every resource and data source: [latest docs](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs). Full examples and attribute tables also live in the [provider repository](https://github.com/appwrite/terraform-provider-appwrite). + +# Terraform block {% #terraform-block %} + +Declare the provider source in a `terraform` block. You can add a `version` constraint when you want to pin a release; see published versions on the [registry provider page](https://registry.terraform.io/providers/appwrite/appwrite/latest). + +```hcl +terraform { + required_providers { + appwrite = { + source = "appwrite/appwrite" + } + } +} +``` + +# Appwrite Cloud {% #appwrite-cloud %} + +Replace `` with your project’s region subdomain (see [Regions](/docs/products/network/regions)). + +```hcl +provider "appwrite" { + endpoint = "https://.cloud.appwrite.io/v1" + project_id = "project-id" + api_key = "api-key" +} +``` + +# Community Edition {% #community-edition %} + +For self-hosted Appwrite, set your instance URL and enable `self_signed` when you use a certificate that is not trusted by default (common in local or internal deployments): + +```hcl +provider "appwrite" { + endpoint = "https://appwrite-instance.com/v1" + project_id = "project-id" + api_key = "api-key" + self_signed = true +} +``` + +# Environment variables {% #environment-variables %} + +You can supply credentials via environment variables instead of hard-coding them in `.tf` files (recommended for CI and local development): + +```bash +export APPWRITE_ENDPOINT="https://.cloud.appwrite.io/v1" +export APPWRITE_PROJECT_ID="project-id" +export APPWRITE_API_KEY="api-key" +``` + +When an environment variable is set, the matching provider argument does not need to appear in the configuration. + +| Provider argument | Environment variable | Required | Description | +|-------------|------------------------|----------|-------------| +| `endpoint` | `APPWRITE_ENDPOINT` | yes | Appwrite API endpoint | +| `project_id` | `APPWRITE_PROJECT_ID` | no | Default project ID for resources (omit if you set `project_id` on each resource) | +| `api_key` | `APPWRITE_API_KEY` | yes | API key with permissions for the resources you manage | +| `self_signed` | - | no | Accept self-signed TLS certificates (Community Edition) | + +# Project scoping {% #project-scoping %} + +You can set `project_id` on the **provider** as the default for all resources, or set `project_id` on **individual resources** when one Terraform configuration manages multiple Appwrite projects. + +# API keys {% #api-keys %} + +Use a key with the scopes required for the resources you manage (for example TablesDB, Storage, Messaging, Functions, Sites, Auth, webhooks, and backups). Follow the principle of least privilege and rotate keys stored outside Terraform. + +# Related {% #related %} + +- [Overview](/docs/tooling/terraform) - full resource list +- [Databases](/docs/tooling/terraform/resources/databases) - TablesDB resources +- [Storage](/docs/tooling/terraform/resources/storage) - buckets and files +- [Messaging](/docs/tooling/terraform/resources/messaging) - providers, topics, and subscribers +- [Self-hosting](/docs/advanced/self-hosting) - install and run the Appwrite server (not the same as configuring project resources with this provider) diff --git a/src/routes/docs/tooling/terraform/resources/auth/+page.markdoc b/src/routes/docs/tooling/terraform/resources/auth/+page.markdoc new file mode 100644 index 0000000000..2517ef0076 --- /dev/null +++ b/src/routes/docs/tooling/terraform/resources/auth/+page.markdoc @@ -0,0 +1,23 @@ +--- +layout: article +title: Auth +description: Manage Appwrite users and teams with the Terraform provider. +--- + +The provider exposes **Auth** resources so you can align users and teams with the rest of your infrastructure-as-code workflow. + +For generated schemas and import syntax, see the Terraform Registry: [auth_user](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs/resources/auth_user) and [auth_team](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs/resources/auth_team). The [provider repository](https://github.com/appwrite/terraform-provider-appwrite) contains source and examples. + +# Resources {% #resources %} + +| Resource | Purpose | +|----------|---------| +| `appwrite_auth_user` | Create and manage users | +| `appwrite_auth_team` | Create and manage teams | + +Use these together with your normal [Auth](/docs/products/auth) and permission models; scope API keys appropriately when Terraform manages identity resources. + +# Related {% #related %} + +- [Configuration](/docs/tooling/terraform/provider) - authentication and endpoints +- [Auth product docs](/docs/products/auth) diff --git a/src/routes/docs/tooling/terraform/resources/backups/+page.markdoc b/src/routes/docs/tooling/terraform/resources/backups/+page.markdoc new file mode 100644 index 0000000000..a638fae7a5 --- /dev/null +++ b/src/routes/docs/tooling/terraform/resources/backups/+page.markdoc @@ -0,0 +1,45 @@ +--- +layout: article +title: Backups +description: Configure Appwrite backup policies with Terraform where your plan supports them. +--- + +The `appwrite_backup_policy` resource configures **backup policies** for supported resources. Availability depends on your Appwrite Cloud plan or self-hosted setup. + +See the Terraform Registry: [backup_policy](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs/resources/backup_policy). The [provider repository](https://github.com/appwrite/terraform-provider-appwrite) lists the full argument reference. + +# Resource {% #resource %} + +| Resource | Purpose | +|----------|---------| +| `appwrite_backup_policy` | Configure backup policies for supported resources | + +Policies use **`schedule`** (CRON), **`retention`** (days), and **`services`** (for example `["databases"]`). Omit **`resource_id`** to cover all databases in the project, or set **`resource_id`** to a specific database ID (often `appwrite_tablesdb.*.id`) to back up one database. + +# Example {% #example %} + +```hcl +resource "appwrite_backup_policy" "daily" { + name = "daily database backup" + services = ["databases"] + retention = 7 + schedule = "0 2 * * *" +} + +resource "appwrite_tablesdb" "main" { + name = "main" +} + +resource "appwrite_backup_policy" "production" { + name = "production database backup" + services = ["databases"] + resource_id = appwrite_tablesdb.main.id + retention = 14 + schedule = "0 */6 * * *" +} +``` + +# Related {% #related %} + +- [Databases](/docs/tooling/terraform/resources/databases) - TablesDB resources you can target with `resource_id` +- [Configuration](/docs/tooling/terraform/provider) - authentication and endpoints diff --git a/src/routes/docs/tooling/terraform/resources/databases/+page.markdoc b/src/routes/docs/tooling/terraform/resources/databases/+page.markdoc new file mode 100644 index 0000000000..ed7e577a0e --- /dev/null +++ b/src/routes/docs/tooling/terraform/resources/databases/+page.markdoc @@ -0,0 +1,122 @@ +--- +layout: article +title: Databases +description: Use Terraform to manage Appwrite TablesDB databases, tables, columns, indexes, and rows with the official Appwrite provider. +--- + +The provider exposes Appwrite **TablesDB** as Terraform resources. Typical order: create a **database** (`appwrite_tablesdb`), then **tables**, then **columns** and **indexes**, and optionally **rows**. + +For full generated schemas, see the Terraform Registry: [tablesdb](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs/resources/tablesdb), [tablesdb_table](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs/resources/tablesdb_table), [tablesdb_column](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs/resources/tablesdb_column), [tablesdb_index](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs/resources/tablesdb_index), and [tablesdb_row](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs/resources/tablesdb_row). The [provider repository](https://github.com/appwrite/terraform-provider-appwrite) contains the source and examples. + +# Resources {% #resources %} + +| Resource | Purpose | +|----------|---------| +| `appwrite_tablesdb` | Create a database in your project | +| `appwrite_tablesdb_table` | Create a table within a database | +| `appwrite_tablesdb_column` | Define columns (types, constraints, defaults) | +| `appwrite_tablesdb_index` | Add indexes on one or more columns | +| `appwrite_tablesdb_row` | Manage rows in a table | + +Relationships use `database_id` and `table_id` references, often wired through Terraform resource attributes (for example `appwrite_tablesdb.main.id`). + +# Example {% #example %} + +This pattern matches the upstream documentation: a database, a `users` table, several columns, and a unique index on email. + +```hcl +resource "appwrite_tablesdb" "main" { + id = "main" + name = "main" +} + +resource "appwrite_tablesdb_table" "users" { + database_id = appwrite_tablesdb.main.id + id = "users" + name = "users" +} + +resource "appwrite_tablesdb_column" "name" { + database_id = appwrite_tablesdb.main.id + table_id = appwrite_tablesdb_table.users.id + key = "name" + type = "varchar" + size = 255 + required = true +} + +resource "appwrite_tablesdb_column" "email" { + database_id = appwrite_tablesdb.main.id + table_id = appwrite_tablesdb_table.users.id + key = "email" + type = "email" + required = true +} + +resource "appwrite_tablesdb_column" "age" { + database_id = appwrite_tablesdb.main.id + table_id = appwrite_tablesdb_table.users.id + key = "age" + type = "integer" + min = 0 + max = 150 +} + +resource "appwrite_tablesdb_column" "role" { + database_id = appwrite_tablesdb.main.id + table_id = appwrite_tablesdb_table.users.id + key = "role" + type = "enum" + elements = ["admin", "editor", "viewer"] + default = "viewer" +} + +resource "appwrite_tablesdb_column" "tags" { + database_id = appwrite_tablesdb.main.id + table_id = appwrite_tablesdb_table.users.id + key = "tags" + type = "varchar" + size = 64 + array = true +} + +resource "appwrite_tablesdb_column" "location" { + database_id = appwrite_tablesdb.main.id + table_id = appwrite_tablesdb_table.users.id + key = "location" + type = "point" +} + +resource "appwrite_tablesdb_index" "email_unique" { + database_id = appwrite_tablesdb.main.id + table_id = appwrite_tablesdb_table.users.id + key = "email_unique" + type = "unique" + columns = [appwrite_tablesdb_column.email.key] +} +``` + +Column `type` supports the types your Appwrite version exposes (for example `varchar`, `email`, `integer`, `enum`, `point`, and more); check the provider docs for the full set. + +# Lookup an existing database (data source) {% #lookup-existing-databases %} + +**Data sources** read resources that already exist instead of creating them. The provider exposes **`appwrite_tablesdb`** so you can reference a database by ID (for example when it was created outside Terraform or in another state). + +See the [Terraform Registry](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs/data-sources/tablesdb) for the full argument list. + +```hcl +data "appwrite_tablesdb" "existing" { + id = "main" +} + +resource "appwrite_tablesdb_table" "example" { + database_id = data.appwrite_tablesdb.existing.id + id = "example" + name = "example" +} +``` + +# Related {% #related %} + +- [Databases product docs](/docs/products/databases) - concepts and Console workflows +- [Configuration](/docs/tooling/terraform/provider) - authentication and endpoints diff --git a/src/routes/docs/tooling/terraform/resources/functions/+page.markdoc b/src/routes/docs/tooling/terraform/resources/functions/+page.markdoc new file mode 100644 index 0000000000..bcda0ddf21 --- /dev/null +++ b/src/routes/docs/tooling/terraform/resources/functions/+page.markdoc @@ -0,0 +1,40 @@ +--- +layout: article +title: Functions +description: Manage Appwrite Functions and function environment variables with Terraform. +--- + +[Functions](/docs/products/functions) can be declared as Terraform resources, including **runtime**, **entrypoint**, **build commands**, **events**, and **per-function environment variables**. + +See the Terraform Registry: [function](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs/resources/function) and [function_variable](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs/resources/function_variable). The [provider repository](https://github.com/appwrite/terraform-provider-appwrite) includes examples. + +# Resources {% #resources %} + +| Resource | Purpose | +|----------|---------| +| `appwrite_function` | Create and update a function (runtime, entrypoint, commands, events, timeout, and related settings) | +| `appwrite_function_variable` | Set environment variables scoped to a function | + +# Example {% #example %} + +```hcl +resource "appwrite_function" "on_signup" { + name = "on-signup" + runtime = "node-22" + entrypoint = "index.js" + commands = "npm install" + events = ["users.*.create"] + timeout = 30 +} + +resource "appwrite_function_variable" "api_url" { + function_id = appwrite_function.on_signup.id + key = "API_URL" + value = "https://api.example.com" +} +``` + +# Related {% #related %} + +- [Functions product docs](/docs/products/functions) +- [Configuration](/docs/tooling/terraform/provider) diff --git a/src/routes/docs/tooling/terraform/resources/messaging/+page.markdoc b/src/routes/docs/tooling/terraform/resources/messaging/+page.markdoc new file mode 100644 index 0000000000..cb98cecd0b --- /dev/null +++ b/src/routes/docs/tooling/terraform/resources/messaging/+page.markdoc @@ -0,0 +1,84 @@ +--- +layout: article +title: Messaging +description: Configure Appwrite Messaging providers, topics, and subscribers with Terraform for email, SMS, and push delivery. +--- + +[Messaging](/docs/products/messaging) integrates email, SMS, and push providers. The Terraform provider exposes **providers** (credentials and channel configuration), **topics** (channels for your messages), and **subscribers** (who receives messages on a topic). + +See the Terraform Registry for generated schemas: [messaging_provider](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs/resources/messaging_provider), [messaging_topic](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs/resources/messaging_topic), and [messaging_subscriber](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs/resources/messaging_subscriber). The [provider repository](https://github.com/appwrite/terraform-provider-appwrite) lists every `type` and optional field in source; provider-specific arguments apply only to the matching provider (for example Twilio `account_sid`, SMTP `host` and `encryption`, FCM `service_account_json`). + +# Resources {% #resources %} + +| Resource | Purpose | +|----------|---------| +| `appwrite_messaging_provider` | Register an email, SMS, or push provider (Sendgrid, SMTP, Twilio, FCM, and others) | +| `appwrite_messaging_topic` | Define a topic for targeting subscribers | +| `appwrite_messaging_subscriber` | Attach subscribers to a topic | + +The `type` argument on `appwrite_messaging_provider` must be one of the supported provider kinds (for example `sendgrid`, `mailgun`, `smtp`, `resend`, `twilio`, `vonage`, `msg91`, `telesign`, `textmagic`, `apns`, `fcm`). + +# Examples {% #examples %} + +## Providers {% #providers %} + +```hcl +resource "appwrite_messaging_provider" "sendgrid" { + id = "sendgrid" + name = "sendgrid" + type = "sendgrid" + api_key = var.sendgrid_api_key + from_email = "noreply@example.com" + from_name = "application" +} + +resource "appwrite_messaging_provider" "smtp" { + id = "smtp" + name = "smtp" + type = "smtp" + host = "smtp.example.com" + port = 587 + username = "user@example.com" + password = var.smtp_password + encryption = "tls" + from_email = "noreply@example.com" +} + +resource "appwrite_messaging_provider" "twilio" { + id = "twilio" + name = "twilio" + type = "twilio" + account_sid = var.twilio_account_sid + auth_token = var.twilio_auth_token + from = "+1234567890" +} + +resource "appwrite_messaging_provider" "fcm" { + id = "fcm" + name = "fcm" + type = "fcm" + service_account_json = file("firebase-service-account.json") +} +``` + +## Topics {% #topics %} + +```hcl +resource "appwrite_messaging_topic" "announcements" { + id = "announcements" + name = "announcements" +} + +resource "appwrite_messaging_topic" "alerts" { + id = "alerts" + name = "alerts" + subscribe = ["users"] +} +``` + +Topics and subscribers support import by ID where documented; see the Registry for each resource. + +# Related {% #related %} + +- [Messaging product docs](/docs/products/messaging) +- [Configuration](/docs/tooling/terraform/provider) diff --git a/src/routes/docs/tooling/terraform/resources/sites/+page.markdoc b/src/routes/docs/tooling/terraform/resources/sites/+page.markdoc new file mode 100644 index 0000000000..2ec5cf06e4 --- /dev/null +++ b/src/routes/docs/tooling/terraform/resources/sites/+page.markdoc @@ -0,0 +1,39 @@ +--- +layout: article +title: Sites +description: Manage Appwrite Sites and site environment variables with Terraform. +--- + +[Sites](/docs/products/sites) supports Terraform resources for the **site** definition and **build-time environment variables** used during deployment. + +See the Terraform Registry: [site](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs/resources/site) and [site_variable](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs/resources/site_variable). The [provider repository](https://github.com/appwrite/terraform-provider-appwrite) includes examples. + +# Resources {% #resources %} + +| Resource | Purpose | +|----------|---------| +| `appwrite_site` | Create and update a site (framework, build and install commands, runtimes, and related settings) | +| `appwrite_site_variable` | Set environment variables for a site (for example `NEXT_PUBLIC_*` keys) | + +# Example {% #example %} + +```hcl +resource "appwrite_site" "dashboard" { + name = "dashboard" + framework = "nextjs" + build_runtime = "node-22" + install_command = "npm install" + build_command = "npm run build" +} + +resource "appwrite_site_variable" "api_url" { + site_id = appwrite_site.dashboard.id + key = "NEXT_PUBLIC_API_URL" + value = "https://api.example.com" +} +``` + +# Related {% #related %} + +- [Sites product docs](/docs/products/sites) +- [Configuration](/docs/tooling/terraform/provider) diff --git a/src/routes/docs/tooling/terraform/resources/storage/+page.markdoc b/src/routes/docs/tooling/terraform/resources/storage/+page.markdoc new file mode 100644 index 0000000000..bf7822e661 --- /dev/null +++ b/src/routes/docs/tooling/terraform/resources/storage/+page.markdoc @@ -0,0 +1,54 @@ +--- +layout: article +title: Storage +description: Manage Appwrite Storage buckets and files with the Terraform provider, including file limits, extensions, compression, and security options. +--- + +The `appwrite_storage_bucket` resource manages [Storage](/docs/products/storage) buckets in your Appwrite project: file size limits, allowed extensions, compression, image transformations, encryption, and optional antivirus. The `appwrite_storage_file` resource uploads and manages **files** inside a bucket from a local path on the machine running Terraform. + +See the Terraform Registry for generated schemas: [storage_bucket](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs/resources/storage_bucket) and [storage_file](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs/resources/storage_file). The [provider repository](https://github.com/appwrite/terraform-provider-appwrite) contains source and examples. + +# Resources {% #resources %} + +| Resource | Purpose | +|----------|---------| +| `appwrite_storage_bucket` | Create and update a storage bucket | +| `appwrite_storage_file` | Upload and manage a file in a bucket (local `file_path`) | + +# Example {% #example %} + +```hcl +resource "appwrite_storage_bucket" "uploads" { + name = "uploads" +} + +resource "appwrite_storage_bucket" "images" { + name = "images" + maximum_file_size = 10485760 + allowed_file_extensions = ["jpg", "png", "webp", "gif"] + compression = "gzip" + transformations = true +} + +resource "appwrite_storage_bucket" "documents" { + name = "documents" + file_security = true + encryption = true + antivirus = true +} + +resource "appwrite_storage_file" "logo" { + bucket_id = appwrite_storage_bucket.images.id + name = "logo.png" + file_path = "assets/logo.png" +} +``` + +Common optional arguments on buckets include `maximum_file_size`, `allowed_file_extensions`, `compression` (`none`, `gzip`, `zstd`), `transformations`, `file_security`, `encryption`, `antivirus`, `enabled`, and `permissions`. Read-only attributes expose `created_at` and `updated_at`. + +Buckets and files support [Terraform import](https://developer.hashicorp.com/terraform/cli/commands/import) where the upstream resource documents an ID format (see the Registry for each resource). + +# Related {% #related %} + +- [Storage product docs](/docs/products/storage) +- [Configuration](/docs/tooling/terraform/provider) diff --git a/src/routes/docs/tooling/terraform/resources/webhooks/+page.markdoc b/src/routes/docs/tooling/terraform/resources/webhooks/+page.markdoc new file mode 100644 index 0000000000..40d4d079f2 --- /dev/null +++ b/src/routes/docs/tooling/terraform/resources/webhooks/+page.markdoc @@ -0,0 +1,48 @@ +--- +layout: article +title: Webhooks +description: Register Appwrite webhooks with Terraform to deliver events to your HTTP endpoints. +--- + +The `appwrite_webhook` resource registers a **URL** and **event** subscriptions so Appwrite can notify your services when resources change. Configure **`tls`** for TLS verification on the webhook URL, **`auth_username`** and **`auth_password`** when your endpoint expects HTTP basic authentication, and read **`secret`** from Terraform state when you verify **incoming** webhook signatures on your server. + +See the Terraform Registry: [webhook](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs/resources/webhook). The [provider repository](https://github.com/appwrite/terraform-provider-appwrite) lists the full argument reference. + +# Resource {% #resource %} + +| Resource | Purpose | +|----------|---------| +| `appwrite_webhook` | Register a webhook URL and subscribe to Appwrite events | + +# Examples {% #examples %} + +## Basic {% #basic %} + +```hcl +resource "appwrite_webhook" "user_events" { + name = "user-events" + url = "https://api.example.com/webhooks/users" + events = ["users.*.create", "users.*.update"] + tls = true +} +``` + +## TLS and HTTP basic auth to your endpoint {% #authenticated %} + +```hcl +resource "appwrite_webhook" "authenticated" { + name = "authenticated webhook" + url = "https://api.example.com/webhooks/secure" + events = ["databases.*.collections.*.documents.*.create"] + auth_username = "webhook" + auth_password = var.webhook_password + tls = true +} +``` + +Use the read-only **`secret`** attribute when configuring **signature verification** for payloads Appwrite sends to your URL (see [Webhooks](/docs/advanced/platform/webhooks) in the platform docs). + +# Related {% #related %} + +- [Configuration](/docs/tooling/terraform/provider) - authentication and endpoints +- [Webhooks](/docs/advanced/platform/webhooks) - event delivery, headers, and signatures diff --git a/src/routes/integrations/terraform-provider/+page.markdoc b/src/routes/integrations/terraform-provider/+page.markdoc new file mode 100644 index 0000000000..cd6e939b9a --- /dev/null +++ b/src/routes/integrations/terraform-provider/+page.markdoc @@ -0,0 +1,41 @@ +--- +layout: integration +title: Terraform provider for Appwrite +description: Manage Appwrite TablesDB, Storage, Auth, Functions, Sites, Messaging, webhooks, backups, and more with HashiCorp Terraform and the official appwrite/appwrite provider. +date: 2026-04-19 +featured: false +isPartner: false +isNew: true +cover: /images/integrations/terraform/cover.png +category: deployments +product: + avatar: '/images/integrations/avatars/terraform.svg' + vendor: Terraform + description: 'Terraform is an infrastructure-as-code tool for building, changing, and versioning infrastructure safely and efficiently.' +platform: + - 'Cloud' + - 'Self-hosted' +images: + - /images/integrations/terraform/cover.png +--- + +[HashiCorp Terraform](https://www.terraform.io/) lets you describe infrastructure and cloud configuration in declarative files, then apply changes in a repeatable way. The official [**appwrite/appwrite**](https://registry.terraform.io/providers/appwrite/appwrite/latest) provider connects Terraform to your Appwrite project so you can manage resources through the same workflows you use for the rest of your stack. + +# How does the integration work? + +The provider talks to the Appwrite API using your endpoint and API key. You declare **resources** (for example TablesDB databases through rows, storage buckets and files, users and teams, functions and sites, messaging providers, topics, subscribers, webhooks, and backup policies) in HCL; Terraform plans and applies changes against Appwrite Cloud or a **Community Edition** instance. + +That gives you **reviewable, versioned configuration**: you can codify how a project is structured, share it with your team, and align environments without re-clicking through the Console for every change. + +# How to implement + +1. Install Terraform on your machine ([install guide](https://developer.hashicorp.com/terraform/install)). +2. Add the provider to your Terraform configuration. See the [**Configuration**](/docs/tooling/terraform/provider) page for `required_providers`, endpoints, and environment variables. +3. Follow the [**Terraform provider**](/docs/tooling/terraform) docs for resource areas you need (for example [**Databases**](/docs/tooling/terraform/resources/databases), [**Storage**](/docs/tooling/terraform/resources/storage), [**Messaging**](/docs/tooling/terraform/resources/messaging), [**Auth**](/docs/tooling/terraform/resources/auth), [**Functions**](/docs/tooling/terraform/resources/functions), [**Sites**](/docs/tooling/terraform/resources/sites), [**Webhooks**](/docs/tooling/terraform/resources/webhooks), and [**Backups**](/docs/tooling/terraform/resources/backups)). +4. Use the [**Terraform Registry**](https://registry.terraform.io/providers/appwrite/appwrite/latest/docs) for generated schemas, arguments, and import syntax for each resource. + +# Read more + +- [Terraform provider documentation](/docs/tooling/terraform) on Appwrite +- [Provider on the Terraform Registry](https://registry.terraform.io/providers/appwrite/appwrite/latest) +- [Source repository](https://github.com/appwrite/terraform-provider-appwrite) on GitHub diff --git a/static/images/avatars/levi-van-noort.png b/static/images/avatars/levi-van-noort.png new file mode 100644 index 0000000000..edfa8c859e Binary files /dev/null and b/static/images/avatars/levi-van-noort.png differ diff --git a/static/images/blog/terraform-provider-appwrite/cover.png b/static/images/blog/terraform-provider-appwrite/cover.png new file mode 100644 index 0000000000..4b5af07797 Binary files /dev/null and b/static/images/blog/terraform-provider-appwrite/cover.png differ diff --git a/static/images/integrations/avatars/terraform.svg b/static/images/integrations/avatars/terraform.svg new file mode 100644 index 0000000000..3e5bb81baf --- /dev/null +++ b/static/images/integrations/avatars/terraform.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/static/images/integrations/terraform/cover.png b/static/images/integrations/terraform/cover.png new file mode 100644 index 0000000000..8c86a023dd Binary files /dev/null and b/static/images/integrations/terraform/cover.png differ diff --git a/static/images/pages/integration/integrations-cover.jpg b/static/images/pages/integration/integrations-cover.jpg new file mode 100644 index 0000000000..0e2a2763bf Binary files /dev/null and b/static/images/pages/integration/integrations-cover.jpg differ