Skip to content

Commit

Permalink
Merge pull request #214 from sassoftware/staging
Browse files Browse the repository at this point in the history
6.1.0 - June 15, 2023
  • Loading branch information
dhoucgitter authored Jun 15, 2023
2 parents 5e8459b + 552917e commit 3492d86
Show file tree
Hide file tree
Showing 14 changed files with 172 additions and 97 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
ARG TERRAFORM_VERSION=1.4.5
ARG AWS_CLI_VERSION=2.7.22
ARG AWS_CLI_VERSION=2.11.21
FROM hashicorp/terraform:$TERRAFORM_VERSION as terraform

FROM amazon/aws-cli:$AWS_CLI_VERSION
Expand Down
2 changes: 1 addition & 1 deletion container-structure-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ commandTests:
- -c
- |
aws --version
expectedOutput: ["aws-cli/2.7.22"]
expectedOutput: ["aws-cli/2.11.21"]

metadataTest:
workdir: "/viya4-iac-aws"
Expand Down
32 changes: 25 additions & 7 deletions docs/user/DockerUsage.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ Now each time you invoke the container, specify the file with the [`--env-file`
Add volume mounts to the `docker run` command for all files and directories that must be accessible from inside the container:

- `--volume=$HOME/.ssh:/.ssh` for [`ssh_public_key`](../CONFIG-VARS.md#required-variables) variable in the `terraform.tfvars` file
- `--volume=$(pwd):/workspace` for a local directory where the `terraform.tfvars` file resides and where the `terraform.tfstate` file will be written.
- `--volume=$(pwd):/workspace` for a local directory where the `terraform.tfvars` file resides and where the `terraform.tfstate` file will be written.

To grant Docker permission to write to the local directory, use the [`--user` option](https://docs.docker.com/engine/reference/run/#user).

**NOTE:** Local references to `$HOME` (or "`~`") need to map to the root directory `/` in the container.
Expand All @@ -52,7 +52,7 @@ docker run --rm --group-add root \
--volume $(pwd):/workspace \
viya4-iac-aws \
plan -var-file /workspace/terraform.tfvars \
-state /workspace/terraform.tfstate
-state /workspace/terraform.tfstate
```

### Create Cloud Resources
Expand All @@ -68,7 +68,7 @@ docker run --rm --group-add root \
viya4-iac-aws \
apply -auto-approve \
-var-file /workspace/terraform.tfvars \
-state /workspace/terraform.tfstate
-state /workspace/terraform.tfstate
```

This command can take a few minutes to complete. Once complete, Terraform output values are written to the console. The `kubeconfig` file for the cluster is written to `[prefix]-eks-kubeconfig.conf` in the current directory, `$(pwd)`.
Expand All @@ -82,7 +82,7 @@ docker run --rm --group-add root \
--user "$(id -u):$(id -g)" \
--volume $(pwd):/workspace \
viya4-iac-aws \
output -state /workspace/terraform.tfstate
output -state /workspace/terraform.tfstate
```

### Modify Cloud Resources
Expand All @@ -98,7 +98,7 @@ docker run --rm --group-add root \
viya4-iac-aws \
apply -auto-approve \
-var-file /workspace/terraform.tfvars \
-state /workspace/terraform.tfstate
-state /workspace/terraform.tfstate
```

### Tear Down Resources
Expand Down Expand Up @@ -127,12 +127,30 @@ docker run --rm --group-add root \
### Example Using `kubectl`

You can run the `kubectl get nodes` command with the `viya4-iac-aws` Docker image in order to get a list of cluster nodes. Switch the entrypoint to kubectl (`--entrypoint kubectl`), provide a kubeconfig file (`--env=KUBECONFIG=/workspace/<your prefix>-eks-kubeconfig.conf`), and pass kubectl subcommands (such as `get nodes`). For example, to run `kubectl get nodes`, run the following command:
You can run the `kubectl get nodes` command with the `viya4-iac-aws` Docker image in order to get a list of cluster nodes. Switch the entrypoint to kubectl (`--entrypoint kubectl`), provide a kubeconfig file (`--env=KUBECONFIG=/workspace/<your prefix>-eks-kubeconfig.conf`), and pass kubectl subcommands (such as `get nodes`). For example, to run `kubectl get nodes`, run one of the following commands that matches your kubeconfig file type:

Using a static kubeconfig file

```bash
docker run --rm \
--env=KUBECONFIG=/workspace/<your prefix>-eks-kubeconfig.conf \
--volume=$(pwd):/workspace \
--entrypoint kubectl \
viya4-iac-aws get nodes
```

Using a provider based kubeconfig file requires AWS cli credentials in order to authenticate to the cluster

```bash
docker run --rm \
--env=KUBECONFIG=/workspace/<your prefix>-eks-kubeconfig.conf \
--volume=$(pwd):/workspace \
--env=AWS_PROFILE=default \
--env=AWS_SHARED_CREDENTIALS_FILE=/workspace/credentials \
--volume $HOME/.aws/credentials:/workspace/credentials \
--entrypoint kubectl \
viya4-iac-aws get nodes
```
See [Kubernetes Configuration File Generation](./Kubeconfig.md) for information related to creating static and provider based kube config files.

You can find more information about using AWS CLI credentials in [Configuring the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-profiles).
33 changes: 33 additions & 0 deletions docs/user/Kubeconfig.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Kubernetes Configuration File Generation

## Overview

Generating a kube config file for the AWS Infrastructure as Code (IaC) repository supports two options.

The options are:

- Provider Based
- Kubernetes Service Account and Cluster Role Binding

### Provider Based - AWS Cloud Provider

This option creates a kube config file that utilizes the `aws` CLI executable from Amazon. This method generates an `access_token` with an expiration time that is refreshed each time you use the kube config file to access your cluster.

Portability is more limited with this option given the file is tied to the authentication method used to create the file.

### Kubernetes Service Account and Cluster Role Binding

This option creates a static kube config file that includes creation of the following:

- Service Account
- Cluster Role Binding

Once created, the `Service Account` is used to provide the `ca cert` and `token` embedded in the kube config file.

This kube config file option is quite portable as the `ca cert` and `token` for the cluster are static. Anyone who has this file can access the cluster.

## Usage

| Name | Description | Type | Default | Notes |
| :--- | ---: | ---: | ---: | ---: |
| create_static_kubeconfig | Allows the user to create a provider- or service account-based kubeconfig file | bool | true | A value of `false` defaults to using the cloud provider's mechanism for generating the kubeconfig file. A value of `true` creates a static kubeconfig that uses a service account and cluster role binding to provide credentials. |
2 changes: 1 addition & 1 deletion main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ module "vpc" {
# EKS Setup - https://github.com/terraform-aws-modules/terraform-aws-eks
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "18.7.1"
version = "18.31.2"
cluster_name = local.cluster_name
cluster_version = var.kubernetes_version
cluster_enabled_log_types = [] # disable cluster control plan logging
Expand Down
13 changes: 11 additions & 2 deletions modules/aws_autoscaling/main.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
# Copyright © 2021-2023, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

terraform {
required_version = ">= 1.4.5"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}

# Permissions based off the IAM Policy recommended by kubernetes/autoscaler
# https://github.com/kubernetes/autoscaler/blob/cluster-autoscaler-chart-9.25.0/cluster-autoscaler/cloudprovider/aws/README.md
data "aws_iam_policy_document" "worker_autoscaling" {
Expand Down Expand Up @@ -59,7 +69,7 @@ resource "aws_iam_policy" "worker_autoscaling" {

module "iam_assumable_role_with_oidc" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
version = "4.1.0"
version = "4.24.1"

create_role = true
role_name = "${var.prefix}-cluster-autoscaler"
Expand All @@ -72,4 +82,3 @@ module "iam_assumable_role_with_oidc" {
}

}

1 change: 1 addition & 0 deletions modules/aws_autoscaling/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ variable "cluster_name" {

variable "tags" {
description = "Tags used for autoscaling"
type = map(any)
default = null
}

Expand Down
12 changes: 11 additions & 1 deletion modules/aws_ebs_csi/main.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
# Copyright © 2021-2023, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

terraform {
required_version = ">= 1.4.5"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}

resource "aws_iam_policy" "ebs_csi" {
name_prefix = "${var.prefix}-ebs-csi-policy"
description = "EKS ebs csi policy for cluster ${var.cluster_name}"
Expand Down Expand Up @@ -157,7 +167,7 @@ EOT

module "iam_assumable_role_with_oidc" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
version = "4.12.0"
version = "4.24.1"

create_role = true
role_name = "${var.prefix}-ebs-csi-role"
Expand Down
1 change: 1 addition & 0 deletions modules/aws_ebs_csi/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ variable "cluster_name" {

variable "tags" {
description = "Tags used for aws ebs csi objects"
type = map(any)
default = null
}

Expand Down
56 changes: 31 additions & 25 deletions modules/kubeconfig/main.tf
Original file line number Diff line number Diff line change
@@ -1,26 +1,47 @@
# Copyright © 2021-2023, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

terraform {
required_version = ">= 1.4.5"
required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.20"
}
local = {
source = "hashicorp/local"
version = "~> 2.4"
}
}
}

locals {
service_account_name = "${var.prefix}-cluster-admin-sa"
cluster_role_binding_name = "${var.prefix}-cluster-admin-crb"
service_account_secret_name = "${var.prefix}-sa-secret"
}

# Provider based kube config data/template/resources
data "template_file" "kubeconfig_provider" {
count = var.create_static_kubeconfig ? 0 : 1
template = file("${path.module}/templates/kubeconfig-provider.tmpl")

vars = {
# Provider based kube config data/template/resources
kubeconfig_provider = var.create_static_kubeconfig ? null : templatefile("${path.module}/templates/kubeconfig-provider.tmpl", {
cluster_name = var.cluster_name
endpoint = var.endpoint
ca_crt = var.ca_crt
region = var.region
}
}
)

# Service Account based kube config data/template/resources
kubeconfig_sa = var.create_static_kubeconfig ? templatefile("${path.module}/templates/kubeconfig-sa.tmpl", {
cluster_name = var.cluster_name
endpoint = var.endpoint
name = local.service_account_name
ca_crt = base64encode(lookup(data.kubernetes_secret.sa_secret[0].data, "ca.crt", ""))
token = lookup(data.kubernetes_secret.sa_secret[0].data, "token", "")
namespace = var.namespace
}
) : null

}

# Service Account based kube config data/template/resources
data "kubernetes_secret" "sa_secret" {
count = var.create_static_kubeconfig ? 1 : 0
metadata {
Expand All @@ -30,21 +51,6 @@ data "kubernetes_secret" "sa_secret" {
depends_on = [kubernetes_secret.sa_secret]
}

data "template_file" "kubeconfig_sa" {
count = var.create_static_kubeconfig ? 1 : 0
template = file("${path.module}/templates/kubeconfig-sa.tmpl")

vars = {
cluster_name = var.cluster_name
endpoint = var.endpoint
name = local.service_account_name
ca_crt = base64encode(lookup(data.kubernetes_secret.sa_secret[0].data, "ca.crt", ""))
token = lookup(data.kubernetes_secret.sa_secret[0].data, "token", "")
namespace = var.namespace
}
depends_on = [data.kubernetes_secret.sa_secret]
}

# 1.24 change: Create service account secret
resource "kubernetes_secret" "sa_secret" {
count = var.create_static_kubeconfig ? 1 : 0
Expand Down Expand Up @@ -88,7 +94,7 @@ resource "kubernetes_cluster_role_binding" "kubernetes_crb" {

# kube config file generation
resource "local_file" "kubeconfig" {
content = var.create_static_kubeconfig ? data.template_file.kubeconfig_sa[0].rendered : data.template_file.kubeconfig_provider[0].rendered
content = var.create_static_kubeconfig ? local.kubeconfig_sa : local.kubeconfig_provider
filename = var.path
file_permission = "0644"
directory_permission = "0755"
Expand Down
2 changes: 2 additions & 0 deletions modules/kubeconfig/templates/kubeconfig-provider.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ users:
- get-token
- --cluster-name
- ${cluster_name}
- --output
- json
command: aws
20 changes: 15 additions & 5 deletions modules/kubeconfig/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ variable "namespace" {
}

variable "region" {
default = null
type = string
default = null
}

variable "create_static_kubeconfig" {
Expand All @@ -22,9 +23,18 @@ variable "create_static_kubeconfig" {
default = false
}

variable "path" {}
variable "cluster_name" {}
variable "endpoint" {}
variable "ca_crt" {}
variable "path" {
type = string
}

variable "cluster_name" {
type = string
}

variable "endpoint" {
type = string
}

variable "ca_crt" {
type = string
}
20 changes: 10 additions & 10 deletions versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,35 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "3.72.0"
version = "3.76.1"
}
random = {
source = "hashicorp/random"
version = "3.1.0"
version = "3.5.1"
}
local = {
source = "hashicorp/local"
version = "2.1.0"
version = "2.4.0"
}
null = {
source = "hashicorp/null"
version = "3.1.0"
}
template = {
source = "hashicorp/template"
version = "2.2.0"
version = "3.2.1"
}
external = {
source = "hashicorp/external"
version = "2.1.0"
version = "2.3.1"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "2.13.0"
version = "2.20.0"
}
tls = {
source = "hashicorp/tls"
version = "3.4.0"
}
cloudinit = {
source = "hashicorp/cloudinit"
version = "2.3.2"
}
}
}
Loading

0 comments on commit 3492d86

Please sign in to comment.