Skip to content

Kubernetes cronjob to make periodical Cloudflare backups in Terraform format

License

Notifications You must be signed in to change notification settings

nullniverse/cloudcron

Repository files navigation

CloudCron

lake and cloud reflection

Kubernetes cronjob to make periodical Cloudflare backups in Terraform format

This project builds atop of cf-terraforming, leveraging all it's features.

Overview

What it contains:

  • Backup artifacts generated recurrently in an automated manner
  • Automation Python script
  • Dockerfile for generating the Docker container
  • Helm Chart for deploying the cronjob in a Kubernetes cluster

This project uses:

  • Terraform 1.8.5
  • Golang 1.22.4
  • Python3 (last version at the image build date)
  • cf-terraforming -dev+79ac2e6f4d66 (last version at the image build date)

This project allows notifications!

Use the available hook to send messages to Google Chats channel or customize it for your preferred tool!

Customize the Gchats channel link in values.yaml.

Generated files:

The following structure are generated for the current resources:

.
└── 2024
    └── 7
        └── 3
            ├── DOMAIN1.COM
            ├── DOMAIN2.COM
            ├── DOMAIN3.COM
            └── ...

The resources are saved this way:

└── DOMAIN1.COM
    ├── cloudflare_access_group.tf
    ├── cloudflare_access_identity_provider.tf
    ├── cloudflare_access_mutual_tls_certificate.tf
    ├── cloudflare_access_rule.tf
    ├── cloudflare_account_member.tf
    ├── cloudflare_argo.tf
    ├── cloudflare_bot_management.tf
    ├── cloudflare_load_balancer_monitor.tf
    ├── cloudflare_load_balancer_pool.tf
    ├── cloudflare_record.tf
    ├── cloudflare_tiered_cache.tf
    ├── cloudflare_url_normalization_settings.tf
    ├── cloudflare_zone_settings_override.tf
    ├── cloudflare_zone.tf
    └── ...

Artifacts

dir structure

├── cloudcron-script.py
├── config.tf
├── Dockerfile
├── generated
│   └── 2024 ...
├── k8s
│   └── Cloudcron-app
├── requirements.txt
└── ssh
    ├── id_ed25519
    └── id_ed25519.pub

cloudcron

  • cloudcron-script.py - Python code responsible for communicating with Cloudflare and Terraform tool
  • config.tf - Terraform Provider configuration for Cloudflare (do not modify)
  • Dockerfile - Dockerfile for generating the Docker container image
  • generated/ - resource terraform files, generated in the backup
  • k8s/ - Helm template for provisioning in Kubernetes
  • requirements.txt - Python requirements used at container build time
  • ssh/ - credentials to connect to Github, used by the application
Artifact Type Used in
account_resources.tsv Passes the list of Terraform resources that are in the scope of Account config-mirroring.py
cf_resources.tsv Resources that are processed in the query to generate configurations, of the type Zone and Account config-mirroring.py
zoneids.tsv List of Zone IDs and Account IDs that the scanner will inspect config-mirroring.py
ssh/id_ed25519 SSH private key used by the account that is Admin of the Github repository Dockerfile
ssh/id_ed25519.pub SSH public key used by the account that is Admin of the Github repository Dockerfile
YOUR-SA-CREDENTIALS.json Service Account used by automation, to connect to Cloud Object Storage config-mirroring.py
API_TOKEN Environment variable containing the Cloudflare API Token used k8s/cloudcron-app/values.yaml
GCHAT_NOTIFICATION Webhook used for notification in Google Chats Space k8s/cloudcron-app/values.yaml

Configuring:

Important

We are aware that providing ssh credentials is not the most noble of things, but we are trading usefulness for security, considering you are aware of risks and running in a self-contained environment

Project configuration

It will hardly be necessary to update the code, unless changes arise in the structure of the cf-terraforming project.

To configure the project on a new cluster, for example, you will need:

  • Make sure that the k8s cluster has access to the Google Artifact Registry (GAR, preferably use it) or any other registry of your chosen
  • Resource limits supported by values ​​passed in values.yaml
  • Release the Service Account used on the Nodes to allow access to Google Object Storage where the .tsv files are stored

Generating a new Docker container image

Choosing a Github account and generating SSH credentials

It will be necessary to modify the files in the /ssh folder by inserting the keys of the account used. Also - if a new image is generated - it will be necessary to change the account email configured in values.yaml {} cronjob > script.

Important

Be careful not to commit the credentials passed at this stage!

After inserting the keys, modify their file attributes:

chmod 644 YOUR-PUBLIC-KEY.pub
chmod 0600 YOUR-PRIV-KEY #(EX: id_ed25519)

When generating the new image, they will be in this path:

/app # cat ~/.ssh/id_ed25519.pub
/app # cat ~/.ssh/id_ed25519

Generating a new image

To generate a new image, make sure there is not one already generated on your machine by docker image ls -a.

  • To generate a new image, run in the project folder:
  • docker build -t cloudcron .

It is important to check if the artifacts were generated correctly, if you want to run the container locally, run: docker run -it cloudcron Now, we will generate a new tag for the container and upload it to our Registry. For that:

  • Enter your registry in gcloud settings (ex: gcloud auth configure-docker us-east4-docker.pkg.dev)
  • If installing in a new, recently created cluster, it will be necessary to configure access to the repository for the cluster's SA, to do this run:
gcloud artifacts repositories add-iam-policy-binding REGISTRY-REPO-NAME/ \
   --location=REGISTRY-LOCATION \
   --member=serviceAccount:[email protected] \
   --role="roles/artifactregistry.reader"

Now, apply the new tag to your image. We use the registry initially configured in this example:

docker tag cloudcron us-docker.pkg.dev/PROJECTNAME/REPONAME/cloudcron:<NEW-VERSION>
docker push us-docker.pkg.dev/PROJECTNAME/REPONAME/cloudcron:<NEW-VERSION>

Installing or upgrading installation on a K8s cluster

The cloudcron namespace was used, change it to the desired one.

Update the image value in your values.yaml to the new image tag (if you generated one);

cd k8s/cloudcron-app
helm template cloudcron-app ./. --values values.yaml

Validate whether the changed information is as desired; Then, apply the upgrade/installation:

helm <upgrade|install> cloudcron-app ./. --namespace cloudcron

If you have changed the Service Account or it is a new installation, you will need to add it as a secret in the cluster:

If you have changed it, run it first:

kubectl delete secret/gcs-sa-key -n cloudcron

Once this is done, apply the SA Key file generated in the cluster as secret:

kubectl create secret generic gcs-sa-key --from-file=SA-JSON-FILE.json=SA-JSON-FILE.json -n cloudcron

Validating the project in Kubernetes

Preferably, upload a zoneids.tsv into your bucket with few entries - two are enough - so that the test doesn't take too long.

If you haven't changed any names in the Helm charts, run the command below to create a Job and run the flow:

kubectl create job --from=cronjob/cloudcron-app-job cloudcron-jobtrial -n cloudcron

Tip

Logs can be monitored via: kubectl logs -f container-name In the current cluster/namespace. You could also try Coroot for metrics and log collection.

Once successfully validated, a folder with the current date will have been created in the path /generated.

After that, perform a git pull in your local project, delete the generated artifacts and commit to main again, to ensure that there are no incomplete backups in the project!

Supported Terraform Features

Warning

Updated List Any resources not listed are currently not supported.

Resource Resource Scope Generate Supported Import Supported
cloudflare_access_application Account
cloudflare_access_group Account
cloudflare_access_identity_provider Account
cloudflare_access_mutual_tls_certificate Account
cloudflare_access_policy Account
cloudflare_access_rule Account
cloudflare_access_service_token Account
cloudflare_account_member Account
cloudflare_api_shield Zone
cloudflare_api_token User
cloudflare_argo Zone
cloudflare_authenticated_origin_pulls Zone
cloudflare_authenticated_origin_pulls_certificate Zone
cloudflare_bot_management Zone
cloudflare_byo_ip_prefix Account
cloudflare_certificate_pack Zone
cloudflare_custom_hostname Zone
cloudflare_custom_hostname_fallback_origin Account
cloudflare_custom_pages Account or Zone
cloudflare_custom_ssl Zone
cloudflare_filter Zone
cloudflare_firewall_rule Zone
cloudflare_healthcheck Zone
cloudflare_ip_list Account
cloudflare_load_balancer Zone
cloudflare_load_balancer_monitor Account
cloudflare_load_balancer_pool Account
cloudflare_logpull_retention Zone
cloudflare_logpush_job Zone
cloudflare_logpush_ownership_challenge Zone
cloudflare_magic_firewall_ruleset Account
cloudflare_origin_ca_certificate Zone
cloudflare_page_rule Zone
cloudflare_rate_limit Zone
cloudflare_record Zone
cloudflare_ruleset Account or Zone
cloudflare_spectrum_application Zone
cloudflare_tiered_cache Zone
cloudflare_teams_list Account
cloudflare_teams_location Account
cloudflare_teams_proxy_endpoint Account
cloudflare_teams_rule Account
cloudflare_tunnel Account
cloudflare_turnstile_widget Account
cloudflare_url_normalization_settings Zone
cloudflare_waf_group Zone
cloudflare_waf_override Zone
cloudflare_waf_package Zone
cloudflare_waf_rule Zone
cloudflare_waiting_room Zone
cloudflare_worker_cron_trigger Account
cloudflare_worker_route Zone
cloudflare_worker_script Account
cloudflare_workers_kv Account
cloudflare_workers_kv_namespace Account
cloudflare_zone Account
cloudflare_zone_dnssec Zone
cloudflare_zone_lockdown Zone
cloudflare_zone_settings_override Zone

References

About

Kubernetes cronjob to make periodical Cloudflare backups in Terraform format

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published