Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AWS EKS Cluster Support #5

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,26 @@ ENV HELM_URL=https://get.helm.sh/helm-v${HELM_VERSION}-linux-amd64.tar.gz
ARG KUBECTL_VERSION=1.19.2
ENV KUBECTL_URL=https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VERSION}/bin/linux/amd64/kubectl

ARG AWS_IAM_AUTHENTICATOR_VERSION=1.18.8/2020-09-18
ENV AWS_IAM_AUTHENTICATOR_URL=https://amazon-eks.s3.us-west-2.amazonaws.com/${AWS_IAM_AUTHENTICATOR_VERSION}/bin/linux/amd64/aws-iam-authenticator

WORKDIR /tmp
RUN true \
&& wget -O helm.tgz "$HELM_URL" \
&& tar xvpf helm.tgz linux-amd64/helm \
&& mv linux-amd64/helm /usr/local/bin/helm \
&& wget -O /usr/local/bin/kubectl "$KUBECTL_URL" \
&& chmod +x /usr/local/bin/kubectl
&& chmod +x /usr/local/bin/kubectl \
&& wget -O /usr/local/bin/aws-iam-authenticator "$AWS_IAM_AUTHENTICATOR_URL" \
&& chmod +x /usr/local/bin/aws-iam-authenticator

# ---

FROM busybox:glibc

COPY --from=downloader /usr/local/bin/helm /usr/local/bin/helm
COPY --from=downloader /usr/local/bin/kubectl /usr/local/bin/kubectl
COPY --from=downloader /usr/local/bin/aws-iam-authenticator /usr/local/bin/aws-iam-authenticator

COPY --from=builder /etc/ssl/certs /etc/ssl/certs
COPY --from=builder /tmp/build/drone-helm3 /usr/local/bin/drone-helm3
Expand Down
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,60 @@ Example:
An always up2date version of the availible config options can be viewed on the
source on the `Config` `struct` [here][1].

## Deploying to EKS

Example:

```yaml
- name: deploy app
image: bitsbeats/drone-helm3
environment:
AWS_DEFAULT_REGION: us-east-1
settings:
kube_api_server: kube.example.com
eks_cluster: my-eks-cluster

chart: ./path-to/chart
release: release-name
namespace: namespace-name
timeout: 20m
helm_repos:
- bitnami=https://charts.bitnami.com/bitnami
envsubst: true
values:
- app.environment=awesome
- app.tag=${DRONE_TAG/v/}
- app.commit=${DRONE_COMMIT_SHA}
```

Role Based EKS Access Example:

```yaml
- name: deploy app
image: bitsbeats/drone-helm3
environment:
AWS_DEFAULT_REGION: us-east-1
settings:
kube_api_server: kube.example.com
eks_cluster: my-eks-cluster
eks_role_arn: arn:aws:iam::[ACCOUNT ID HERE]:role/[ROLE HERE]

chart: ./path-to/chart
release: release-name
namespace: namespace-name
timeout: 20m
helm_repos:
- bitnami=https://charts.bitnami.com/bitnami
envsubst: true
values:
- app.environment=awesome
- app.tag=${DRONE_TAG/v/}
- app.commit=${DRONE_COMMIT_SHA}
```

**Note**:
Depending on your setup you might also need to pass `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` to the environment.

## Monitoring

Its possible to monitor your builds and rollbacks using prometheus and
Expand Down
33 changes: 32 additions & 1 deletion internal/kube/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ type (
Certificate string
SkipTLS bool
Namespace string
EKSCluster string
EKSRoleARN string
}

Option func(*kubeConfig)
Expand All @@ -39,7 +41,21 @@ clusters:
users:
- name: helm
user:
{{- if .Token }}
token: {{ .Token }}
{{- else if .EKSCluster }}
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
command: aws-iam-authenticator
args:
- "token"
- "-i"
- "{{ .EKSCluster }}"
{{- if .EKSRoleARN }}
- "-r"
- "{{ .EKSRoleARN }}"
{{- end }}
{{- end }}

contexts:
- name: helm
Expand Down Expand Up @@ -67,6 +83,18 @@ func WithToken(token string) Option {
}
}

func WithEKSCluster(eksCluster string) Option {
return func(k *kubeConfig) {
k.EKSCluster = eksCluster
}
}

func WithEKSRoleARN(eksRoleARN string) Option {
return func(k *kubeConfig) {
k.EKSRoleARN = eksRoleARN
}
}

func WithCertificate(certificate string) Option {
return func(k *kubeConfig) {
k.Certificate = certificate
Expand Down Expand Up @@ -96,9 +124,12 @@ func CreateKubeConfig(options ...Option) error {
if k.ApiServer == "" {
return fmt.Errorf("no kubernetes api server provided")
}
if k.Token == "" {
if k.Token == "" && k.EKSCluster == "" {
return fmt.Errorf("no kubernetes token provided")
}
if k.Token != "" && k.EKSCluster != "" {
return fmt.Errorf("token cannot be used simultaneously with eksCluster")
}
if k.Namespace == "" {
return fmt.Errorf("no namespace provided")
}
Expand Down
55 changes: 54 additions & 1 deletion internal/kube/kube_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,49 @@ contexts:
user: helm
`,
},
{
options: []Option{
WithConfig(kubeconfig),
WithApiServer("https://example.com"),
WithCertificate("CERTDATA"),
WithEKSCluster("eks_cluster"),
WithEKSRoleARN("my-eks-role-arn"),
WithNamespace("myapp"),
},
want: `
apiVersion: v1
kind: Config

current-context: "helm"
preferences: {}

clusters:
- name: helm
cluster:
server: https://example.com
certificate-authority-data: CERTDATA

users:
- name: helm
user:
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
command: aws-iam-authenticator
args:
- "token"
- "-i"
- "eks_cluster"
- "-r"
- "my-eks-role-arn"

contexts:
- name: helm
context:
cluster: helm
namespace: myapp
user: helm
`,
},
{
options: []Option{
WithConfig(kubeconfig),
Expand Down Expand Up @@ -137,10 +180,20 @@ contexts:
options: []Option{
WithConfig(kubeconfig),
WithApiServer("https://example.com"),
WithToken("token"),
WithEKSCluster("eks_cluster"),
WithNamespace("myapp"),
},
err: fmt.Errorf("no kubernetes token provided"),
err: fmt.Errorf("token cannot be used simultaneously with eksCluster"),
},
{
options: []Option{
WithConfig(kubeconfig),
WithApiServer("https://example.com"),
WithNamespace("myapp"),
},
err: fmt.Errorf("no kubernetes token provided"),
},
{
options: []Option{
WithConfig(kubeconfig),
Expand Down
6 changes: 5 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ type (
KubeSkip bool `envconfig:"KUBE_SKIP" default:"false"` // skip creation of kubeconfig
KubeConfig string `envconfig:"KUBE_CONFIG" default:"/root/.kube/config"` // path to kubeconfig
KubeApiServer string `envconfig:"KUBE_API_SERVER" required:"true"` // kubernetes api server
KubeToken string `envconfig:"KUBE_TOKEN" required:"true"` // kubernetes token
KubeToken string `envconfig:"KUBE_TOKEN"` // kubernetes token
KubeCertificate string `envconfig:"KUBE_CERTIFICATE"` // kubernetes http ca
KubeSkipTLS bool `envconfig:"KUBE_SKIP_TLS" default:"false"` // disable kubernetes tls verify
EKSCluster string `envconfig:"EKS_CLUSTER"` // AWS EKS Cluster ID to put in kubeconfig
EKSRoleARN string `envconfig:"EKS_ROLE_ARN"` // AWS IAM role resource name to put in kubeconfig

PushGatewayURL string `envconfig:"PUSHGATEWAY_URL" default:""` // url to a prometheus pushgateway server

Expand Down Expand Up @@ -110,6 +112,8 @@ func main() {
kube.WithConfig(cfg.KubeConfig),
kube.WithApiServer(cfg.KubeApiServer),
kube.WithToken(cfg.KubeToken),
kube.WithEKSCluster(cfg.EKSCluster),
kube.WithEKSRoleARN(cfg.EKSRoleARN),
kube.WithNamespace(cfg.Namespace),
kube.WithCertificate(cfg.KubeCertificate),
kube.WithSkipTLS(cfg.KubeSkipTLS),
Expand Down