How to apply yaml file on terraform? - kubernetes

How do I do this but in terraform using kubernetes provider??
kubectl apply -k "github.com/kubernetes-sigs/aws-efs-csi-driver/deploy/kubernetes/overlays/stable/?ref=release-1.4"
I have searched for a few, but none mention applying a direct yaml file.

You can achieve that differently; if that works for you. You want to execute kubectl from Terraform, not communicating directly with the Kubernetes API.
I think this method has more advantages than what you originally asking for, because it removes an external dependency.
There's a kubectl provider you can use. You can download the YAML and commit it with your Terraform code. That way it is also easier to review changes to the YAML (between versions).
It would look something like this:
resource "kubectl_manifest" "test" {
yaml_body = <<YAML
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
azure/frontdoor: enabled
spec:
rules:
- http:
paths:
- path: /testpath
pathType: "Prefix"
backend:
serviceName: test
servicePort: 80
YAML
}

I would suggest you use the aws-efs-csi-driver Helm Chart and further using the helm terraform provider.
Would be easy and neat.
## refer to the provider documentation to configure accordingly this is the simplest example.
provider "helm" {
kubernetes {
config_path = "~/.kube/config"
}
resource "helm_release" "aws_efs_csi_driver" {
name = "aws-efs-csi-driver"
repository = "https://kubernetes-sigs.github.io/aws-efs-csi-driver/"
chart = "aws-efs-csi-driver"
set {
### Your custom values ###
}
}

Related

Haproxy ingress and regex pathType

I'm migrating an architecture to kubernetes and I'd like to use the Haproxy ingress controller that I'm installling with helm, according the documentation (version 1.3).
Thing is, when I'm defining path rules through an ingress file, I can't define Regex or Beging path types as seen on documentation here : https://haproxy-ingress.github.io/docs/configuration/keys/#path-type.
My configuration file :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: bo-ingress
annotations:
haproxy.org/path-rewrite: "/"
kubernetes.io/ingress.class: haproxy
spec:
rules:
- host: foo.com
http:
paths:
- path: /
pathType: Beging
backend:
service:
name: foo-service
port:
number: 80
When I install my ingress helm chart with this configuration, I have that error message :
Error: UPGRADE FAILED: cannot patch "bo-ingress" with kind Ingress: Ingress.extensions "bo-ingress" is invalid: spec.rules[2].http.paths[12].pathType: Unsupported value: "Begin": supported values: "Exact", "ImplementationSpecific", "Prefix"
Am I missing something ? Is this feature only available for Enterprise plan ?
Thanks, Greg
HAProxy Ingress follows “Ingress v1 spec”, so any Ingress spec configuration should work as stated by the Kubernetes documentation.
As per the kubernetes documentation, the supported path types are ImplementationSpecific, Exact and Prefix. Paths that do not include an explicit pathType will fail validation. Here the path type Begin is not supported as per kubernetes documentation. So use either of those 3 types.
For more information on kubernetes supported path types refer to the documentation.

Are there any versioning for kubernetes ingress?

I want to know if there is versioning for ingress config similar to what we have in deployments. Suppose there is a misconfiguration I would like to revert to the previous config.
I would like to understand about generation in ingress YAML config.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/service-match: 'new-nginx: header("foo", /^bar$/)' #Canary release rule. In this example, the request header is used.
nginx.ingress.kubernetes.io/service-weight: 'new-nginx: 50,old-nginx: 50' #The route weight.
creationTimestamp: null
generation: 1
name: nginx-ingress
selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/nginx-ingress
spec:
rules: ##The Ingress rule.
- host: foo.bar.com
http:
paths:
- backend:
serviceName: new-nginx
servicePort: 80
path: /
- backend:
serviceName: old-nginx
servicePort: 80
path: /
Kubernetes does not offer this natively, and neither does a management tool like Rancher.
If you want to do this, you need an infra-as-code tool, like Terreform, ansible, etc. The config files for these can be versioned in a repo.
Even without those, you can independently export a give ingress yaml, and commit it to a repo.
Slightly different way to look at a solution - you could use gitOps. I mean that you could put all your yaml's in a git repo, install ArgoCD on your cluster and then simply let ArgoCD do the syncing for you. The moment you realised you've messed something up in a yaml file, just revert the commit in the git repo. That way you maintain history and get a graceful non-opinionated solution.

Kubernetes and failover service

I have next situation and I am not sure if it is possible to achieve it using kubernetes only.
There are two pods, one with live service is available on e.g. givemedata.example.com, temporary one on givemedata2.example.com. Temporary one is without any dependency and there just to allow some long term jobs to continue run while real one is down for maintenance.
Cluster is on GKE.
I need to setup failover so that if live one is down for maintenance, failover should redirect calls to temporary one.
Main reason is to use only one endpoint, e.g. givemedata.example.com.
My question is if this is possible and how to do it?
You can install NGINX ingress controller. Add
nginx.ingress.kubernetes.io/server-snippet: annotation to ingress configuration file and add block of code which will check if domain is available, if not it will redirect traffic to different one.
Thanks to this annotation it is possible to add custom configuration in the server configuration block.
Read more: server snippet.
Remember to add this server to nginx.conf file in /etc/nginx directory.
Here is example cofiguration:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
namespace: ingress-nginx
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/add-base-url : "true"
nginx.ingress.kubernetes.io/configuration-snippet: |
set $agentflag 0;
if ($http_user_agent ~* "(Mobile)" ){
set $agentflag 1;
}
if ( $agentflag = 1 ) {
return 301 https://givemedata2.example.com;
}
spec:
rules:
- host: givemedata.example.com
http:
paths:
- path: /
backend:
serviceName: service-name
servicePort: service-port

Trying to rewrite url for Grafana with Ingress

In my kubernetes cluster I would like to do monitoring so I installed grafana.
I would like to access the grafana dashboard as http://example.com/monitoring, so I tried to include this in my ingress configuration
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: example.com
http:
paths:
- path: /monitoring/(.*)
backend:
serviceName: grafana
servicePort: 80
The idea is to add other paths there as well, for example / for the website.
I noticed that Grafana redirects http://example.com/monitoring to http://example.com/login. Of course this should have been http://example.com/monitoring/login. What would be the preferred way to fix this. Can it be done with ingress or should I somehow tell Grafana that it is behind a /monitoring path (if possible)?
I've installed grafana using this using Helm.
UPDATE: I've modified as suggested below the grafana chart's file values.yaml as follows
grafana.ini:
server:
domain: example.com
root_url: http://example.com/monitoring/
Now I get:
And the heml command I use to install grafana:
$> helm install stable/grafana -f values.yaml --set persistence.enabled=true --set persistence.accessModes={ReadWriteOnce} --set persistence.size=8Gi -n grafana
This is a common problem with services that are behind an HTTP reverse-proxy. Luckily, Grafana offers a way to let it know the context path it is running behind.
In grafana.ini (which is most possibly supplied via a ConfigMap to its Kubernetes deployment), you need to specify the variables like the following:
[server]
domain = example.com
root_url = http://example.com/monitoring/
See the full documentation here: https://grafana.com/docs/installation/behind_proxy/

Can later ingress subpaths override earlier ingress parent paths?

I have a Kubernetes ingress that I want to be the default for all paths on a set of hosts, provided there is not a more specific match:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: default-ing
spec:
rules:
- host: host1.sub.example.com
http:
paths:
- backend:
serviceName: my-default-service
servicePort: http
# Note: here we specify the root path intended as a default
path: /
- backend:
serviceName: my-default-service
servicePort: http
path: /route/path/to/default
A second ingress defines a custom service for a specific path:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: special-ing
spec:
rules:
- host: host1.sub.example.com
http:
paths:
- backend:
serviceName: special-service
servicePort: http
path: /special
I would expect that the order of adding/deleting the ingresses would not matter, or at least I could have some way of indicating that the path: / in default-ing is always to be ordered last.
When I try the above, the routing is fine as long as I add special-ing before default-ing (or alternatively, add default-ing, then the special-ing, then delete default-ing and re-add it again). When I add them as default-ing, then special-ing, requests to /special are routed to my-default-service instead of special-service.
I want the order of adding/deleting to be independent of the routing that is generated by nginx-ingress-controller, so that my kubectl manipulations are more robust, and if one of the ingresses is recreated nothing will break.
I'm using nginx-ingress-controller:0.19.0
Thanks for any help you can offer!
The short answer is no. I believe your configs should be disallowed by the nginx ingress controller or documented somewhere. Basically what's happening when you have 2 hosts rules with the same value: host1.sub.example.com one is overwriting the other in the server {} block in the nginx.conf that your nginx ingress controller is managing.
So if your add default-ing before special-ing then special-ing will be the actual config. When you add special-ing before default-ing then default-ing will be your only config, special-ing is not supposed to work at all.
Add special-ing, and the configs look something like this:
server {
server_name host1.sub.example.com;
...
location /special {
...
}
location / { # default backend
...
}
...
}
Now add default-ing, and the configs will change to like this:
server {
server_name host1.sub.example.com;
...
location /route/path/to/default {
...
}
location / { # default backend
...
}
...
}
If you add them the other way around the config will look like 1. in the end.
You can find more by shelling into your nginx ingress controller pod and looking at the nginx.conf file.
$ kubectl -n <namespace> exec -it nginx-ingress-controller-pod sh
# cat /etc/nginx/nginx.conf
Update 03/31/2022:
It seems like on newer nginx ingress controller versions. All the rules with the same host get merged into a server block in the nginx.conf