Google Container Registry images lifecycle - google-cloud-platform

I would like to know if there is a way to setup an objects lifecycle in GCP Container Registry?
I would like to keep the last n versions of an image, automatically deleting the older ones as new ones are pushed online.
I can't work directly on the Cloud Storage bucket because, having multiple images saved, the storage objects are not recognizable.

Seth Vargo, a Google Cloud developer advocate has release GCRCleaner.
Follow the instruction for setting up a scheduler and a Cloud Run for cleaning the GCR.

Unfortunaltely, there is no concept pf managed lifecycle management of images managed in GCR just like there is in AWS which allows creating policies to manage images in the registry.
You have to plan this yourself i.e. a script which emulates the following behavior and runs periodically.
gcloud container images delete -q --force-delete-tags "${IMAGE}#${digest}"

Unfortunately, at this time there’s no feature able to do such in GCR, however there’s already a feature request created. You can follow on it and write comments.
Also check this example, where image deletion was implemented in specific time.

Related

High Surge usage on Storage and bandwidth when deploying Cloud / Firebase Functions

I have a 3.8gb usage on my Google Cloud Storage , and I don't know why , I deleted all my buckets from console (Cloud Storage) but still it has data in it , later on I dinged deeper and fond the following page it has loads of data including Cloud Functions and strange buckets , any idea how to clean my app on Google Cloud for those potential junk data that keeps on growing for some reason ?
The 3.81 GB usage on your Google Cloud Storage shown in your Firebase dashboard is normal because the Cloud Functions is now integrating the use of Cloud Build in the deployment process.
Deployments work by uploading an archive containing your function's source code to a Cloud Storage bucket. Once the source code has been uploaded, Cloud Build automatically builds your code into a container image and pushes that image to either Artifact Registry or Container Registry. Cloud Functions uses that image to create the container that executes your function.
With this pipeline, the Artifacts buckets are created automatically in order to store the containerized functions.
As you can see on this thread, it is safe to delete the images stored in your buckets if you desire. This can be achieved by setting lifecycle deletion rules on the artifacts buckets to mitigate additional costs generated by an excess of build images.
Note: As mentioned by #JohnHanley, the bucket that starts with gcf-sources is your Cloud Functions source code. If you delete it, you will not be able to see your source code in the source tab in your functions.
Sample screenshot if the source code in your Functions is deleted in the bucket:

Google Container Registry : Prevent a group of users to push reserved tag names

I need to restrict some users to push 'latest' or 'master' tags to a shared GCR repository, only automated process like jenkins should be able to push this tags, is that possible?
Is there a way to do this like AWS Iam policies and conditions?
I think not but it's an interesting question.
I wondered whether IAM conditions could be used but neither Container Registry nor Artifact Registry are resources that accept conditional bindings.
Container Registry uses Cloud Storage and Cloud Storage is a resource type that accepts bindings (albeit only on buckets). However, I think tags aren't manifest (no pun intended) at the GCS level.
One way to approach this would be limit container pushes to your automated processes and then add some process (workflow) in which developers can request restricted tags and have these applied only after approval.
Another approach would be to audit changes to the registry.
Google Artifact Registry (GAR) is positioned as a "next generation" (eventual replacement?) of GCR. With it, you can have multiple repositories within a project that could be used as a way to provide "free-for-all" and "restricted" repositories. I think (!?) even with GAR, you are unable to limit pushes by tag.
You could submit a feature request on Google's Issue Tracker for registries but, given Google's no new features on GCR, you may be out of luck.

Avoid expiring any ECR image if an ECS cluster is still referencing it

We are implementing lifecycle policies to clean up old ECR images but we want to avoid expiring any image if a Fargate ECS cluster is still referencing it. How can we best do that?
I am thinking about adding a "live" tag that is being set and unset by the Blue-Green Switch, but there is a problem - 2 or more environments in our AWS CodePipeline might be using the same image so I would need to implement some kind of reference counting.
Is there a better way, or should I go with this approach?
Unfortunately using lifecycle rules to manage images is just not ideal with AWS.
Multiplatform images (amd64 + arm64) are managed in registries by having a top level meta image that points to other images depending on platform (this is a bit of a simplification). When you tag your image it only tags the top level meta one, not the lower level ones. As such it's possible to accidentally erase images.
As you've discovered images can be erased even if they are referenced somewhere.
Instead of using lifecycle rules I use a simple script, which in turn includes any logic I want. You can run a filter to see what ECS services exist and are using the image and then exclude any where that comes back empty. This is much simpler if everything is in the same account.
To put this another way- instead of having your services push tags to your images, have your deletion script explicitly confirm that no images which are being used get deleted. Then you don't have to worry about how many environments are running it.

How do I ensure that my customer does not misuse my solution offered via Google Cloud Marketplace

I am planning to deploy a vm solution on Google Cloud Marketplace. I have two concerns about this.
I have read this document and it mentions that google cloud images can be exported to cloud storage. Can this method be used to run the image in a local environment.
The VM solution I am providing contains an application binary. If customer copies this binary on some other machine, he will be able to run it. How do I prevent that from happening.
Forgive me if my questions are absurd. I am not able to find answers to these questions anywhere.
The method described in your provided link states that Cloud Storage is it’s only possible destination. I have looked into it and so far I haven’t found another way through the console to do this. I have as well looked into the gcloud command to see if it could once again come to the rescue - so far no luck. Though I am not sure if this would suit your needs you can download objects from buckets in Cloud Storage. So in a way you can get the image (if it’s an object) downloaded to your local environment.
As for your second question , about preventing someone from copying your application binary, what you are asking is copy protection. This is where I quote something from the GCP console itself :
Cloud Storage IDs
Project members can access Cloud Storage data according to their project roles. To modify other permissions, use these group IDs to identify these roles.
Which may or may not suit your needs ( as it pertains to Cloud Storage on not on-premises).

How do you create a gcr repo with terraform?

https://www.terraform.io/docs/providers/google/d/google_container_registry_repository.html
There is a data source but no resource.
gcr seems to have no direct API. Is there a workaround for create a gcr repo with terraform? Can I create a folder in that "artifacts" bucket that gcr uses? Is there a way to manually terraform a gcr repo?
First, Terraform notion of google_container_registry_repository seems incomplete, because it represents only "root repositories" :
gcr.io/[PROJECT_ID]
[REGION].gcr.io/[PROJECT_ID], where [REGION] can be us, eu or asia
Whereas "repository" (in GCP terminology) can also refer to :
[REGION].gcr.io/[PROJECT_ID]/my-repo
[REGION].gcr.io/[PROJECT_ID]/my-repo/my-sub-repo
...
There is no notion of these types of repositories in Terraform data source.
That being said :
"root repositories" cannot be created and are managed by Google (if a new region xy appears, then xy.gcr.io will be created by Google)
other repositories used to order images (for example, a repository per developer or per project) seems kind of an abstract notion, more something like directories in Google Cloud Storage. They are created "on-the-fly" when you push an image, and they do not exist if there is no image in it. To complete the analogy between GCS directories and GCR repositories, note that there are also no google_storage_bucket_directory resources
For the latter kind of repositories (my-repo, my-repo/my-subrepo), the underlying storage bucket cannot be configured : it will always be artifacts.[PROJECT-ID].appspot.com or [REGION].artifacts.[PROJECT-ID].appspot.com, depending of the "root repository". There is no way to isolate different repositories in different buckets.
So in conclusion : you cannot create a GCR repository, whether it be with Terraform, with gcloud, from the web UI, etc.
You can create GCRs using Terraform but you can't destroy them or change region, the problem is with how GCR is implemented by Google rather than a limitation of Terraform.
As norbjd explained (pretty well imho) GCR is like a front-end for buckets that store container images.
GCP doesn't seem to have a concept of deleting GCRs at all, you have to delete the underlying bucket. Terraform can't handle this because it's like saying "when you apply use resource A but when you destroy use resource B".
To destroy you need some other mechanism, either manually deleting the bucket(s) or running a gcloud command for instance.
This simple code will create a repo, and will report as destroyed successfully by terraform destroy but will still appear in Container Registries in your project (and maybe incurring storage costs):
# This creates a global GCR in the current project.
# Though it actually creates the multi-region bucket 'artifacts.[PROJECT_ID].appspot.com'
resource "google_container_registry" "my_registry" {
}