How to Kubectl Apply Multiple Files: A Deep Dive
June 6, 2026
To apply multiple Kubernetes manifest files, use kubectl apply -f for all files in a folder, specify multiple -f flags for specific files, or pipe them via standard input. For advanced environment management, use kubectl apply -k with Kustomize. Proper file organization and robust error handling are crucial for reliable, large-scale deployments.
Applying Multiple Kubernetes Manifests
The kubectl apply -f command is a fundamental tool for managing Kubernetes resources declaratively. It enables users to apply configurations defined in YAML or JSON files to a Kubernetes cluster. When dealing with complex applications composed of multiple resources, kubectl apply -f offers several convenient ways to process them simultaneously.
Applying a Directory of Files
One of the most common and efficient ways to apply multiple files is to point kubectl apply -f to a directory. This command will recursively process all .yaml, .yml, and .json files within that directory and its subdirectories, applying them to the cluster.
For example, if you have a directory named manifests containing deployment.yaml, service.yaml, and configmap.yaml, you can apply all of them with a single command:
kubectl apply -f manifests/
This approach is particularly useful for deploying entire applications or sets of related resources, such as those for Crossplane providers, as it simplifies the command and ensures all necessary components are processed.
Applying Specific Multiple Files
You can also specify multiple individual files directly in the kubectl apply -f command by using the -f flag for each file. This method is useful when your manifest files are not all in the same directory, when you need to apply a specific subset of files from a directory, or when you want to be explicit about the order of application.
For instance, to apply rds-subnet-group.yaml and rds-instance.yaml in a single operation:
kubectl apply -f rds-subnet-group.yaml -f rds-instance.yaml
This command applies both configurations sequentially within a single transaction to the Kubernetes API server.
Applying Files from Standard Input
For greater flexibility, especially in automated environments, kubectl apply -f - can apply configurations piped from standard input (stdin). This can be combined with shell commands like cat or find to dynamically process multiple files. This method is highly powerful in automation pipelines, as a CI/CD job can use it to deploy manifests without creating intermediate files.
For example, to apply all YAML files in the current directory:
find . -name "*.yaml" -exec cat {} + | kubectl apply -f -
This command finds all files ending in .yaml, concatenates their content, and pipes the result directly to kubectl apply.
Applying Overlays with Kustomize
For managing configuration variations across different environments (e.g., development, staging, production), Kustomize provides a powerful, template-free solution. It is built directly into kubectl. Instead of using the -f flag, you use -k to point to a directory containing a kustomization.yaml file.
The kustomization.yaml file specifies a set of base resources and overlays (patches) to apply for a specific environment.
## Apply the configuration defined by the kustomization.yaml in the 'overlays/production' directory kubectl apply -k overlays/production/
This approach allows you to maintain a clean separation between base configurations and environment-specific changes, making your deployments more organized and maintainable.
Best Practices for Organizing Manifest Files
How you organize your manifest files is as important as how you apply them. Adopting infrastructure-as-code (IaC) principles ensures your deployments are reproducible, auditable, and scalable.
Monorepo vs. Polyrepo Strategy
A key architectural decision is whether to store your Kubernetes configurations in a monorepo or multiple repositories (polyrepo).
- Monorepo: A single repository holds all configurations. This provides a single source of truth and simplifies cross-cutting changes, making it suitable for small to medium teams. However, it can have a larger blast radius if something goes wrong.
- Polyrepo: Each application or team has its own repository. This grants teams more autonomy and isolates the blast radius of changes. It's often preferred by large organizations but introduces the complexity of managing dependencies and potential configuration drift between repositories.
Environment-Specific Configurations
A common pattern is to structure your directories by environment. This isolates environment configurations and works seamlessly with Git branches for promotion workflows (e.g., merging changes from staging to prod).
A typical structure might look like this, often used with Kustomize:
├── base/
│ ├── deployment.yaml
│ └── service.yaml
└── overlays/
├── development/
│ ├── kustomization.yaml
│ └── replica-count.yaml
└── production/
├── kustomization.yaml
└── resource-limits.yaml
This structure separates the base YAML from the patches that customize it for each environment.
Pinning Versions and Ensuring Idempotency
For predictable and stable deployments, always pin versions. In Kubernetes manifests, this most commonly refers to container image tags. Avoid using "floating" tags like :latest or :stable. Instead, use specific, immutable tags like nginx:1.26.0.
This practice prevents unexpected changes from being pulled into your deployments and is a foundational principle of GitOps. kubectl apply itself is idempotent: running it multiple times with the same file will only apply changes if the live state has drifted from the desired state in the file, ensuring consistent results.
Error Handling and Validation
When you run kubectl apply -f on multiple files, the process stops on the first error. This can leave your application in a partially deployed or inconsistent state. Robust error handling and validation strategies are essential to prevent this.
Preventative Enforcement with Admission Controllers
A powerful way to catch errors before they are applied is to use Kubernetes admission controllers. Policy engines like OPA/Gatekeeper or Kyverno can intercept API requests generated by kubectl apply and validate them against a set of rules.
For example, a policy can be written to reject any deployment that uses an image with a :latest tag. When a developer tries to apply such a manifest, the API server rejects the request with an error message explaining the violation. The developer must then update the manifest to a pinned tag like nginx:1.26.0 before the configuration can be successfully applied. This preventative approach is far safer than detecting non-compliant resources after they are already running in the cluster.
Auditing and Guardrails in GitOps
In a GitOps workflow, tools like Argo CD or Flux continuously apply the desired state from a Git repository to one or more clusters. This provides a reproducible pipeline and a clear audit trail. These tools also offer advanced error handling and safety features.
For example, Argo CD's AppProject CRD acts as a governance mechanism, defining guardrails for applications:
sourceRepos: Whitelists which Git repositories an application can be deployed from.destinations: Restricts deployments to specific clusters and namespaces, which is critical for enforcing data residency requirements.namespaceResourceWhitelist: Controls which types of Kubernetes resources an application is allowed to create.
By defining these guardrails, platform teams can automate safe multi-cluster deployments and ensure that developers can only apply configurations that comply with organizational policies.
Use Cases for Applying Multiple Files
The ability to apply multiple files is central to modern Kubernetes operations, especially when managing infrastructure as code.
Deploying Crossplane Providers
When setting up Crossplane, you often need to install multiple providers to interact with different cloud services. These providers are defined in separate YAML manifests. For example, to install AWS and Azure providers, you might have a providers.yaml file containing definitions for provider-aws and provider-azure.
apiVersion: pkg.crossplane.io/v1 kind: Provider metadata: name: provider-aws spec: package: xpkg.upbound.io/upbound/provider-aws-s3:v1.16.0 --- apiVersion: pkg.crossplane.io/v1 kind: Provider metadata: name: provider-azure spec: package: xpkg.upbound.io/upbound/provider-azure-storage:v1.9.0
This providers.yaml file, containing multiple Kubernetes resources separated by ---, can be applied with a single command:
kubectl apply -f providers.yaml
This creates both provider-aws and provider-azure resources in the cluster. Similarly, a file like provider-aws.yaml can define multiple AWS-specific providers (S3, RDS, EC2) and be applied in one go.
Building Compositions and Claims
Crossplane Compositions allow platform teams to bundle multiple managed resources (e.g., a database, network, security group) into a single custom API. This involves defining a CompositeResourceDefinition (XRD) and a Composition. Developers then use a "Claim" (XRC) to request this bundled infrastructure.
A typical workflow might involve applying several YAML files:
xrd-database.yaml: Defines the schema for the composite resource.composition-database.yaml: Implements the composition, mapping XRD fields to real AWS Managed Resource fields.claim-database.yaml: The developer's request for the infrastructure.
Each of these files would be applied using kubectl apply -f, often from a directory containing the entire application stack.
Comparison: Crossplane vs. Terraform
While kubectl apply -f is a core Kubernetes command, its application in infrastructure management with Crossplane can be compared to tools like Terraform.
| Dimension | Crossplane | Terraform |
|---|---|---|
| State storage | Kubernetes etcd (the live object IS the state) | Remote backend (S3 + DynamoDB, Terraform Cloud) |
| Execution model | Continuous reconciliation loop (operator pattern) | One-shot apply triggered by CI/CD |
| Drift detection | Real-time, automatic correction | Only on the next plan/apply run |
| API surface | Kubernetes CRDs — standard kubectl, RBAC, GitOps | HCL files, Terraform CLI, workspaces |
| Self-service | Claims let developers request infra without knowing AWS | Requires a Terraform module call or portal |
| Composability | Compositions with patches and transforms | Modules with input variables |
| Secrets | Kubernetes Secrets (or ESO) | Terraform outputs, encrypted state |
| Maturity | CNCF graduated (2024), broad provider ecosystem | Industry standard, 10+ years, vast registry |
| Best for | Platform teams building internal developer platforms | Ops teams managing multi-cloud, complex dependencies |
Crossplane leverages kubectl apply -f as its primary interface for managing infrastructure, integrating deeply with Kubernetes' native capabilities like RBAC and GitOps. Terraform, on the other hand, uses its own CLI and HCL language.
Frequently Asked Questions
What is the primary command to apply multiple Kubernetes files?
The primary command is kubectl apply -f, which can be followed by a directory path or multiple file paths to apply several Kubernetes manifest files simultaneously.
Can I apply all YAML files in a directory using a single command?
Yes, you can apply all .yaml, .yml, and .json files within a directory and its subdirectories by running kubectl apply -f <directory_path>/.
What is the difference between `kubectl apply -f` and `kubectl apply -k`?
kubectl apply -f applies resources from specified files or directories, while kubectl apply -k applies resources defined by a kustomization.yaml file, enabling environment-specific overlays.
How does `kubectl apply -f` handle updates to existing resources?
When kubectl apply -f is used on an existing resource, it performs a three-way merge patch, applying only the changes specified in the manifest file while preserving other fields.
What happens if an error occurs when applying multiple files?
The kubectl apply command will stop on the first file that fails to apply, potentially leaving your application in a partially deployed state.
Is `kubectl apply -f` suitable for GitOps workflows?
Yes, kubectl apply -f is highly suitable for GitOps workflows, as it allows infrastructure configurations stored in Git to be automatically applied to the Kubernetes cluster, ensuring the desired state is maintained.
Conclusion
Applying multiple Kubernetes manifest files is a common and essential task. The kubectl apply command provides flexible options, from applying an entire directory with -f to leveraging environment-specific overlays with -k. However, effective management goes beyond the command line. Success depends on adopting best practices for organizing your manifest files, pinning versions for predictability, and implementing robust validation with admission controllers and GitOps guardrails. By combining these powerful command-line techniques with a structured, policy-driven approach, teams can manage complex applications reliably and at scale.
Sources & References
- API Security Platforms For Kubernetes 2026
- Data Residency Compliance: Enterprise Governance Guide | Airbyte
- DevOps Maturity Model Guide: Self-Assessment & Key Steps
- From Terraform to Crossplane: Exploring Multi-Cloud infrastructure management | by Christian Dussol | AWS in Plain English
- What is Idempotency in Terraform and Ansible | by Mohammed Affan | AWS in Plain English
- 9 Extraordinary Terraform Best Practices That Will Rock Your Infrastructure
- Infrastructure as Code (IaC) on OVHcloud - part 1: Terraform / OpenTofu - OVHcloud Blog
- Sovereign Cloud Guide: How to Solve 2026 Data Residency Laws
- GitOps and Continuous Delivery for Cloud-Native Applications 2026 - Calmops
- GitOps 2026 Complete Guide - Calmops
Want to actually learn DevOps & Cloud Infrastructure?
Curo turns topics like this into a personalized, guided learning board - built around what you already know. Free to start.