TL;DR तुमच्याकडे एक static site आणि एक domain आहे. Cloudflare Pages ती serve करते, Terraform तुमच्या repo मधल्या काही files वरून hosting उभी करते, R2 मध्ये Terraform ची आठवण राहते, आणि तुम्ही push केल्यावर GitHub Actions हे सगळं चालवतं. बिल शून्य. उदाहरण repo ही रचना एका वेळी एक commit अशी दाखवते.

या लेखाची पहिली आवृत्ती मी २०२१ मध्ये लिहिली. २०१९ पासून मी मित्र आणि कुटुंबासाठी काही sites AWS वर host करत होतो: files साठी S3, समोर CloudFront, आणि Cloudflare फक्त DNS साठी. Route53 दर domain दरमहा अर्धा डॉलर घेत होतं, इतक्या छोट्या sites साठी S3 आणि CloudFront मिळून जेवढं होत होतं त्याहून जास्त. तो लेख हा खर्च वाचवण्याबद्दल होता.

Cloudflare Pages २०२१ मध्ये beta मधून बाहेर आलं, मोफत plan सोबत. sites तेव्हाच हलवता आल्या असत्या, पण Terraform ची state Cloudflare वर ठेवायला जागा नव्हती. R2 एका वर्षाने आलं आणि २०२४ पर्यंत state lock करू शकत नव्हतं, आणि काही kilobyte state साठी S3 चं बिल काही cents होतं. म्हणून state S3 वरच राहिली.

Terraform 1.10 ने २०२४ च्या शेवटी S3 native locking आणलं, आणि ते ज्या conditional write वर अवलंबून आहे ती R2 पाळतं. त्याने AWS account ठेवायचं शेवटचं कारण संपलं. sites Pages वर गेल्या, आणि या आठवड्यात state R2 वर गेली. हा लेख मी आता या blog साठी आणि त्याच sites साठी वापरतो ती रचना सांगतो.

हे कोणासाठी आहे Link to heading

तुम्ही Vite, Astro, Hugo, React, Vue, Next.js किंवा साध्या HTML ने site बनवली आहे. तुमच्याकडे domain आहे, किंवा तो विकत घ्यायला दहा डॉलर आहेत. तुम्हाला ती site त्या domain वर HTTPS सोबत चालू हवी आहे, आणि server साठी पैसे द्यायचे नाहीत किंवा पुढच्या वेळी आठवणीने dashboard मधून click करत बसायचं नाही.

तुम्हाला Terraform, R2 किंवा GitHub Actions माहीत असायची गरज नाही. प्रत्येकाची खाली थोडक्यात ओळख आहे, आणि अधिक हवं असेल तर official docs ची link.

कल्पना Link to heading

तुमच्या git repository मध्ये तीन गोष्टी असतात: site च्या files, hosting चं वर्णन, आणि push झाल्यावर चालवायच्या steps ची यादी. main वर push करा, आणि काही मिनिटांत site तुमच्या domain वर live. site बदला, पुन्हा push करा. hosting बदला, पुन्हा push करा. लक्षात ठेवायचं काही नाही, click करायचं काही नाही.

चार tools हे शक्य करतात.

Cloudflare Pages Cloudflare च्या network वर static files host करतं, HTTPS आणि <name>.pages.dev पत्त्यासोबत. त्याला तुम्ही स्वतःचा domain जोडता. मोफत plan ला bandwidth ची मर्यादा नाही. Pages docs.

Terraform infrastructure ला text files मध्ये बदलतं. तुम्हाला काय हवं ते लिहून ठेवता, एक Pages project आणि एक DNS record, आणि terraform apply चालवता. Terraform Cloudflare API ला call करून ते तयार करतं. file बदला आणि पुन्हा चालवा, फक्त जे वेगळं आहे तेवढंच बदलतं. What is Terraform.

R2 ही Cloudflare ची file storage आहे. Terraform एक छोटी file ठेवतं, तिला state म्हणतात, त्यात काय तयार केलं याची नोंद असते. Terraform फक्त तुमच्या laptop वरून चालवत असाल तर ती file तिथेच राहू शकते. GitHub Actions प्रत्येक run ला नव्या machine वर सुरू होतं, म्हणून ती file कुठेतरी shared ठेवावी लागते. shared file ने दुसरी अडचण येते: दोन runs एकाच वेळी ती लिहिल्या तर ती बिघडते, म्हणून storage ला lock ही जमला पाहिजे. R2 दोन्ही करतं. R2 docs आणि Terraform state.

GitHub Actions तुम्ही push केल्यावर GitHub च्या servers वर commands चालवतं. repo मधली एक YAML file steps सांगते. Understand GitHub Actions.

Terraform काय सांभाळतं Link to heading

दोन गोष्टी. तुमचा domain जोडलेलं Pages project, आणि domain ला project कडे नेणारं एक CNAME record. संपूर्ण वर्णन एका screen मध्ये मावतं. हे project.

#  Pages project. Cloudflare creates it on the first apply.
resource "cloudflare_pages_project" "site" {
  account_id        = var.cloudflare_account_id
  name              = var.project_name
  production_branch = "main"
}

#  Your domain on that project. Cloudflare issues the certificate.
resource "cloudflare_pages_domain" "site" {
  account_id   = var.cloudflare_account_id
  project_name = cloudflare_pages_project.site.name
  name         = var.site_name
}

प्रत्येक resource block म्हणजे Cloudflare तयार करणार असलेली एक गोष्ट. var. values एका छोट्या file मधून येतात जी तुम्ही एकदाच भरता, म्हणून तीच Terraform कोणत्याही site साठी चालते. DNS record तसंच दिसतं आणि dns.tf मध्ये आहे.

state Terraform च्या S3 backend मार्फत R2 वर जाते, कारण R2 S3 protocol बोलतं. connection चे तपशील backend.config मधल्या अकरा ओळी आहेत, Cloudflare च्या guide मधून घेतलेल्या. तुम्ही एक ओळ बदलता, bucket चं नाव.

remote state उभी करणं एक command आहे. ती नंतर हलवणं, माझ्या बाबतीत S3 वरून R2 वर, पहिल्या दोन वेळा मला घाबरवून गेलं. file हरवली, समजा backup घ्यायच्या आधी bucket delete केली, किंवा ती बिघडली, तर तुमच्या sites चालू राहतात पण Terraform काय तयार केलं ते विसरतं. पुढचा apply सगळं पुन्हा तयार करू पाहतो आणि आधीच असलेल्या नावांवर अडतो. उपाय म्हणजे import block ने प्रत्येक असलेल्या resource ची Terraform ला ओळख करून देणं, जे resources जास्त असतील तर कंटाळवाणं होतं. कोणत्याही हलवाहलवीआधी state चा backup घ्या.

push वर काय चालतं Link to heading

workflow प्रत्येक push ला, कोणत्याही branch वर चालतो.

  1. Terraform files ची formatting तपासा आणि validate करा.
  2. R2 मधल्या state ला connect करा.
  3. Plan: files ची जे अस्तित्वात आहे त्याच्याशी तुलना करा, काय बदलेल ते छापा.

main वर तो पुढे जातो.

  1. तो plan apply करा.
  2. Cloudflare चं command line tool Wrangler वापरून site/ Pages project वर upload करा.

म्हणजे branch वरचा push हा dry run आहे. pull request उघडा, job log मध्ये plan वाचा, merge करा, आणि main तेच खरोखर करतो. tokens कधीच YAML मध्ये नसतात. ते repository secrets मधून येतात आणि environment variables म्हणून Terraform पर्यंत पोहोचतात. file आहे deploy.yml.

plan आणि apply वेगळ्या steps असण्याची दोन कारणं आहेत.

पहिलं, apply तुम्ही main पुरतं मर्यादित ठेवता आणि plan तुमच्या infrastructure चा diff म्हणून वाचता. data blocks वापरायला लागल्यावर plan ची खरी किंमत कळते. एखादा id किंवा नाव resource मध्ये paste करण्याऐवजी तुम्ही तो live API मधून शोधता, आणि चुकीचा शोध apply नंतर नाही तर plan च्या वेळीच fail होतो. static values नी मला एकाहून जास्त वेळा चावलं आहे, dashboard मधून copy केलेला id जो नंतर कोणीतरी पुन्हा तयार केला.

दुसरं, बदलांचा side effect म्हणून apply गोष्टी नष्ट करतं. तुमचं DNS record Terraform ने सांभाळा, आणि name field मधली एक चुकीची key xyz.example.com चं jxyz.example.com करते. Terraform जुनं record delete करतं, नवं तयार करतं, आणि success सांगतं. तुम्हाला कळेपर्यंत, किंवा smoke test ला कळेपर्यंत, तुमची site बंद. vim च्या सवयीचा j, VS Code मध्ये टाइप झालेला, हे माझ्या बाबतीत एकाहून जास्त वेळा घडलं आहे. plan वाचणं ते पकडतं, आणि record वर prevent_destroy असलेला lifecycle block ते पूर्ण अडवतो.

उभारणी Link to heading

उदाहरण repo हेच tutorial आहे. प्रत्येक commit एक step आहे आणि README मध्ये स्वतःचा भाग जोडतो, म्हणून git log --reverse वरून खाली वाचता येतो.

  1. पूर्वतयारी: email, GitHub account, एक card, Node.js.
  2. Cloudflare account.
  3. Domain: Cloudflare Registrar वर विकत घ्या, किंवा असलेला हलवा.
  4. R2 चालू करा, state bucket तयार करा.
  5. दोन API tokens, प्रत्येक एका bucket किंवा एका zone पुरतं.
  6. site च्या files.
  7. Terraform files: दोन values बदला.
  8. workflow file: एक value बदला.
  9. GitHub repo, पाच secrets, push, live होताना पाहा.
  10. स्वतःच्या machine वरून deploy, workflow चालवतो त्याच commands. ऐच्छिक.
  11. सगळं मोडून टाकणं.

steps १ ते ५ dashboard चं काम आहे आणि पहिल्या वेळी साधारण अर्धा तास घेतात. steps ६ ते ९ म्हणजे एक copy, दोन बदल आणि एक push. Terraform स्वतः तुमच्या machine वर कधीच चालवावं लागत नाही.

AWS आणि Cloudflare ची जोडी सुरुवातीच्या दिवसांत खडतर होती, त्यात ACM सगळ्यात जास्त: हाताने तयार केलेले validation records, दोन providers मधला trailing dot चा फरक, apex वर CNAME flattening, आणि एक wildcard आणि एक नावाचा domain एकच certificate वापरत असताना state चे conflicts. एकदा apply पार पडला की शांत राहायचं. नव्या provider versions नी यातलं प्रत्येक सोडवलं, आणि वरची फक्त Cloudflare ची रचना ACM ला हातही लावत नाही. जी infrastructure टिकवायची आहे तिच्यासाठी मी अजूनही लोकांना Terraform किंवा OpenTofu कडे पाठवतो.

वर GitHub Actions असलं की ही फेरी दिसेनाशी होते. मी phone वरून एक typo दुरुस्त करतो, commit करतो, आणि तपासायला उघडेपर्यंत site बदललेली असते. कोणतंही CI हे करतं. मी Jenkins मधून आलो आणि हीच रचना GitLab, Drone आणि CircleCI वर चालवली आहे. मी GitHub Actions वर राहतो कारण एका job मध्ये runner step आणि container step शेजारी शेजारी बसतात, आणि कारण YAML ला बरीच वर्षं anchors किंवा references नव्हते. प्रत्येक pipeline सारखीच वाचली जाते, ती लिहिणाऱ्याचे ठसे न घेता.

खर्च आणि मर्यादा Link to heading

बाब 2021 आता
Hosting S3 आणि CloudFront, cents Pages, मोफत
DNS Cloudflare, मोफत Cloudflare, मोफत
Certificate ACM, मोफत Pages, मोफत
Terraform state S3, cents R2, मोफत
Accounts AWS आणि Cloudflare Cloudflare

बिलावर domain ही एकच ओळ. मोफत ला मर्यादा असतात, आणि ही रचना ज्यांना स्पर्श करू शकते त्या या. values १६ सप्टेंबर २०२६ रोजी link केलेल्या pages वर तपासल्या.

सेवा मोफत plan ची मर्यादा स्रोत
Cloudflare Pages महिन्याला 500 builds, एका वेळी 1. प्रत्येक upload ला 20,000 files आणि प्रत्येक file 25 MiB. 100 projects, प्रत्येकाला 100 custom domains. bandwidth किंवा requests ची मर्यादा दिलेली नाही. Pages limits
Cloudflare R2 10 GB storage, महिन्याला 1 million writes आणि 10 million reads. egress चा खर्च नाही. चालू करायला card लागतं. R2 pricing
GitHub Actions public repos वर मोफत. private repos: महिन्याला 2,000 minutes आणि 500 MB artifacts. Actions billing
Cloudflare API प्रत्येक user ला पाच मिनिटांत 1,200 requests. एक Terraform run मूठभर करतो. API limits

आठवड्यातून काही वेळा deploy होणारा blog या सगळ्यांच्या खूप आत राहतो. 500 builds ची ओळ Cloudflare चं स्वतःचं build system मोजते; इथला workflow तयार files upload करतो, आणि ते मोजलं जातं का हे docs सांगत नाहीत. आठवड्याला काही pushes असताना फरक पडत नाही.

सारांश Link to heading

एक repository site, तिची hosting सांगणारी Terraform, आणि दोन्ही पाठवणारा workflow ठेवते. Cloudflare Pages files serve करतं, एक CNAME तुमचा domain तिकडे नेतं, आणि R2 lock सोबत Terraform ची state ठेवतं. प्रत्येक push plan दाखवतो; main वरचा push तो apply करतो आणि site upload करतो.

उभारणी म्हणजे Cloudflare वर domain, एक bucket, दोन tokens, पाच GitHub secrets आणि दोन बदललेल्या values. त्यानंतर dashboard बंदच राहतं. बिल म्हणजे domain. उदाहरण repo प्रत्येक step commit म्हणून नोंदवते, आणि ही site आणि आणखी काही त्याच files वर चालतात.

पुढे काय Link to heading

Preview URLs. branch वरच्या pushes ला upload step मध्ये --branch=${{ github.ref_name }} द्या आणि प्रत्येक branch ला स्वतःचा <branch>.<project>.pages.dev पत्ता मिळतो. Direct upload docs.

zone मधलं आणखी Terraform मध्ये. redirects, email routing, firewall rules हे प्रत्येक त्याच folder मधला आणखी एक resource block. Cloudflare’s Terraform guide.


static site ला स्वतःहून एक गोष्ट जमत नाही: contact form. माझा AWS Lambda वर चालत होता आणि आता Cloudflare Worker वर चालतो. या volume ला दोन्ही मोफत आहेत, आणि एक cloud म्हणजे जिवंत ठेवायचा एक login कमी. त्या हलवाहलवीला स्वतःचा लेख मिळेल.