Restricting access to namespaces based on labels - kubernetes

I've got a cluster with a number of already existing namespaces, and an automatization process that creates (and manages) new namespaces using Terraform.
The service account used for TF got the roles with permission to all namespaces - as I believe this is the only possible solution (TF needs them to manage namespaces).
But due to that, it is also able to modify (& delete) the namespaces that were created before, outside the Terraform processing - and this is something I'd like to prevent/block.
So here's my question - is it possible to restrict this automatization process from modifying already existing namespaces?
The idea to distinguish between old and new namespace is to simply add labels to the new ones created by TF, but I am not aware of any mechanism that could then prohibit modifications based on such labels...
*Admission controllers seem remotely suitable, but I'm completely new to that topic and not sure if those can be used for such purposes.

Related

How to pass values between CDK stacks deployed in different accounts within a CDK app?

Reading from the documentation, the suggestion for passing values between CDK Stacks within an app is to simply pass the value.
If the two stacks are in the same AWS CDK app, just pass a reference between the two stacks. For example, save a reference to the resource's construct as an attribute of the defining stack (this.stack.uploadBucket = myBucket), then pass that attribute to the constructor of the stack that needs the resource.
But it seems this only works if the CDK stacks are within one account.
Upon checking the generated templates, it generates a stack Output and Input and uses that for the passing values. And stack input and outputs does not work beyond the account they are created on.
What's the recommended way to pass values from stacks deployed in different accounts?
I don't think you can think about this as being a single CDK application. Such a single application is intended to be deployed in a single account. What you are trying to do is use this application construct to deploy two different stacks in two different environments and share data between them. However, you are bound to the same restrictions that CloudFormation itself has when it comes to sharing data from services that have been deployed in the stack. So you'll have to work around this issue.
So I don't think there is any recommended way of doing this, but maybe you can create some cross-account roles that allow writing/reading from the SSM parameter store and combine this with custom resource lambdas to read/write the data from/in the SSM store of the other account. Given this, it might be easier to just write some CICD tooling that does this without needing any AWS services and which just passes on the value from the output of one stack to the input of the other stack during deployment.

How to recursively get dependent resources of Kubernetes owner resource

With Kubernetes you can use the Garbage Collector to automate the deletion of dependent resources when owning resources are removed. I'm wondering the easiest method to print out the dependency tree of an owning resource, potentially limiting to a tree depth if needs be.
I understand the potential for crashing the API service given the ability to fan out to all resources in a cluster and likely why this isn't an easy feat to achieve but I've been struggling to even find usable, community supported workarounds or even discussions/issues relating to this topic (likely my poor searching skills) so any help in achieving this would be great!
To make things more concrete a specific example of an abstract kubectl get query I'd like to achieve would be something like kubectl get scheduledworkflow <workflow name> --dependents:
This would find the Kubeflow Pipelines ScheduledWorkflow resource then recurse,
That would find all Argo Workflow resources,
Then for each Workflow resource many Pod and Volume resources (there are a few other types but wanted to paint the picture of these being disparate resource types).
We typically only keep a small number of Argo Workflow resources in the cluster at anyone one time as the majority of our Workflow's spawn 1k+ Pod so we have pretty aggressive GC policies in place. Even so listing these is just painful at the moment and need to use a custom script to do it but wondering if there was a higher level CLI, SDK or API available (or any group working on this issue in the community!).
There are no ready solutions for this.
I see two options how this can be proceeded:
1 - probably this is what you already mentioned: "need to use a custom script to do it".
Idea is to get jsons of required resource groups and then process it by any available/known language like bash/python/java/etc and/or using jq. All dependent objects have ownerReference field which allows to match resources.
More information about owners and dependents
jq tool and examples
2 - Write your own tool based on kubernetes garbage collector
Kubernetes garbage collector works based on graph built by GraphBuilder:
garbage collector source code
Graph is always up to date by using `reflectors:
GarbageCollector runs reflectors to watch for changes of managed API
objects, funnels the results to a single-threaded
dependencyGraphBuilder, which builds a graph caching the dependencies
among objects
graph_builder source code to get whole logic of it.
Built graph has node type:
graph data structure
Also it's worth to mention that working with api server is more convenient using kubernetes clients libraries which are available for different languages.

Is it possible to get a full configuration from a namespace

I am looking for keeping some kind of baseline for everything applied to kubernetes(or just a namespace).
Like versioning microservices in a list and then check that in to github, in case of the need to roll something back.
Check out Velero, it is a backup tool for kubernetes. I don’t think it can use git as a backend, but you could add that (or use s3 or similar).
You can write and deploy an application that Watch the resources you are interested in, e.g. all Deployment, Service and Ingress... including all changes, and then store the changes as you want. I can recommend client-go for this kind of service.
However
Like versioning microservices in a list and then check that in to github, in case of the need to roll something back.
It is more common, and recommended to work the other way around, first save your intended desired state in Git, have an CICD service to apply your changes in the cluster or clusters. This way of working is called Infrastructure as Code. The new edition of the book Kubernetes Up&Running have a new chapter (18) that describes how to work in this way.

Do CloudFormation target name or resources?

I am currently pending between using terraform and CloudFormation.
There is a question I haven't seen the answer yet (or maybe, I just haven't found it yet).
In terraform, you give a precise name to everything. This will delete the targets with those names.
But what about CF? If we already have an architecture in place and I want to add/delete an instance and use CF, how will this work? How will it know after which one to target?
I hope this question makes sense! I've already used terraform, but never before CloudFormation.
CloudFormation uses two mechanisms to identify its resources. The CFN template has a list of resources it created, it uses the actual ID, not a pretty name, and CFN also tags the resources (that support tags) with the stack ID.
CFN cannot be used to delete the resources in a different stack, only the stack that created them can manage them. Terraform allows you to import resources created by anything else into a new stack where they will be managed.
I used CFN for a year before converting to Terraform (also for a year now) and I'll never go back to CFN. Terraform offers many advantages over CFN that make CFN really hard to use now. Features such as plan before apply, re-usable modules, resource imports, granular output (CFN is mostly a black box), and generally faster AWS feature support (usually APIs are released at launch day and Terraform support follows soon after, /usually/ faster than CFN but not always).

Google Cloud Platform IAM setting to allow project level RO access to buckets

I want to give a service account read-only access to every bucket in my project. What is the best practice for doing this?
The answers here suggest one of:
creating a custom IAM policy
assigning the Legacy Bucket Viewer role on each bucket
using ACLs to allow bucket.get access
None of these seem ideal to me because:
Giving read-only access seems too common a need to require a custom policy
Putting "Legacy" in the name makes it seem like this permission will be retired relatively soon and any new buckets will require modification
Google recommends IAM over ACL and any new buckets will require modification
Is there some way to avoid the bucket.get requirement and still access objects in the bucket? Or is there another method for providing access that I don't know about?
The closest pre-built role is Object Viewer. This allows listing and reading objects. It doesn't include storage.buckets.get permission, but this is not commonly needed - messing with bucket metadata is really an administrative function. It also doesn't include storage.buckets.list which is a bit more commonly needed but is still not part of normal usage patterns for GCS - generally when designing an app you have a fixed number of buckets for specific purposes, so listing is not useful.
If you really do want to give a service account bucket list and get permission, you will have to create a custom role on the project. This is pretty easy, you can do it with:
gcloud iam roles create StorageViewerLister --project=$YOUR_POJECT --permissions=storage.objects.get,storage.objects.list,storage.buckets.get,storage.buckets.list
gcloud projects add-iam-policy-binding $YOUR_PROJECT --member=$YOUR_SERVICE_ACCOUNT --role=StorageViewerLister