Skip to content

Commit 1ea1772

Browse files
Adding ALB troubleshooting scenario and Troubleshooting Methodologies
1 parent 72983ba commit 1ea1772

33 files changed

+1457
-0
lines changed
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
terraform {
2+
required_providers {
3+
# kubectl = {
4+
# source = "gavinbunney/kubectl"
5+
# version = ">= 1.14"
6+
# }
7+
}
8+
}
9+
10+
11+
12+
provider "aws" {
13+
region = "us-east-1"
14+
alias = "virginia"
15+
}
16+
17+
locals {
18+
tags = {
19+
module = "troubleshooting"
20+
}
21+
}
22+
23+
data "aws_vpc" "selected" {
24+
tags = {
25+
created-by = "eks-workshop-v2"
26+
env = var.addon_context.eks_cluster_id
27+
}
28+
}
29+
30+
data "aws_subnets" "public" {
31+
tags = {
32+
created-by = "eks-workshop-v2"
33+
env = var.addon_context.eks_cluster_id
34+
}
35+
36+
filter {
37+
name = "tag:Name"
38+
values = ["*Public*"]
39+
}
40+
}
41+
42+
43+
resource "time_sleep" "blueprints_addons_sleep" {
44+
depends_on = [
45+
module.eks_blueprints_addons
46+
]
47+
48+
create_duration = "15s"
49+
destroy_duration = "15s"
50+
}
51+
52+
53+
resource "null_resource" "break_public_subnet" {
54+
triggers = {
55+
#cluster_id = var.addon_context.eks_cluster_id
56+
public_subnets = join(" ", data.aws_subnets.public.ids)
57+
timestamp = timestamp()
58+
}
59+
count = length(data.aws_subnets.public)
60+
61+
provisioner "local-exec" {
62+
when = destroy
63+
command = "aws ec2 create-tags --resources ${self.triggers.public_subnets} --tags Key=kubernetes.io/role/elb,Value='1'"
64+
}
65+
66+
provisioner "local-exec" {
67+
command = "aws ec2 delete-tags --resources ${self.triggers.public_subnets} --tags Key=kubernetes.io/role/elb,Value='1'"
68+
}
69+
}
70+
71+
72+
module "eks_blueprints_addons" {
73+
source = "aws-ia/eks-blueprints-addons/aws"
74+
version = "1.16.2"
75+
76+
enable_aws_load_balancer_controller = true
77+
aws_load_balancer_controller = {
78+
wait = true
79+
}
80+
81+
cluster_name = var.addon_context.eks_cluster_id
82+
cluster_endpoint = var.addon_context.aws_eks_cluster_endpoint
83+
cluster_version = var.eks_cluster_version
84+
oidc_provider_arn = var.addon_context.eks_oidc_provider_arn
85+
86+
tags = merge(
87+
var.tags,
88+
local.tags
89+
)
90+
91+
depends_on = [null_resource.break_public_subnet]
92+
93+
}
94+
95+
96+
# create a new policy from json file
97+
resource "aws_iam_policy" "issue" {
98+
name = "issue"
99+
path = "/"
100+
policy = file("${path.module}/template/other_issue.json")
101+
}
102+
103+
# attach issue policy to role
104+
resource "aws_iam_role_policy_attachment" "issue_policy_attachment" {
105+
role = module.eks_blueprints_addons.aws_load_balancer_controller.iam_role_name
106+
policy_arn = aws_iam_policy.issue.arn
107+
depends_on = [module.eks_blueprints_addons, time_sleep.blueprints_addons_sleep]
108+
}
109+
110+
resource "null_resource" "detach_existing_policy" {
111+
triggers = {
112+
role_name = module.eks_blueprints_addons.aws_load_balancer_controller.iam_role_name,
113+
timestamp = timestamp()
114+
}
115+
116+
provisioner "local-exec" {
117+
command = "aws iam detach-role-policy --role-name ${self.triggers.role_name} --policy-arn ${module.eks_blueprints_addons.aws_load_balancer_controller.iam_policy_arn}"
118+
when = create
119+
}
120+
121+
depends_on = [aws_iam_role_policy_attachment.issue_policy_attachment]
122+
}
123+
124+
resource "null_resource" "kustomize_app" {
125+
triggers = {
126+
always_run = timestamp()
127+
}
128+
129+
provisioner "local-exec" {
130+
command = "kubectl apply -k ~/environment/eks-workshop/modules/troubleshooting/alb/creating-alb"
131+
when = create
132+
}
133+
134+
depends_on = [aws_iam_role_policy_attachment.issue_policy_attachment]
135+
}
136+
137+
138+
139+
# Example to now how to get variables from add ons outputs DO-NOT-DELETE; AddOns and helms documentaitons does not show exactly the output variables returned
140+
#resource "null_resource" "blue_print_output" {
141+
# for_each = module.eks_blueprints_addons.aws_load_balancer_controller
142+
# triggers = {
143+
#
144+
# timestamp = timestamp()
145+
# }
146+
#
147+
# #count = length(module.eks_blueprints_addons.aws_load_balancer_controller)
148+
# provisioner "local-exec" {
149+
# command = "mkdir -p /eks-workshop/logs; echo \" key: ${each.key} Value:${each.value}\" >> /eks-workshop/logs/action-load-balancer-output.log"
150+
# }
151+
#
152+
# depends_on = [module.eks_blueprints_addons,time_sleep.blueprints_addons_sleep]
153+
#}
154+
155+
#option to run a bash script file
156+
#resource "null_resource" "break2" {
157+
# provisioner "local-exec" {
158+
# command = "${path.module}/template/break.sh ${path.module} mod2"
159+
# }
160+
#
161+
# triggers = {
162+
# always_run = timestamp()
163+
# }
164+
# depends_on = [module.eks_blueprints_addons,time_sleep.blueprints_addons_sleep]
165+
#}
166+
167+
#option to run a kubectl manifest
168+
#resource "kubectl_manifest" "alb" {
169+
# yaml_body = templatefile("${path.module}/template/ingress.yaml", {
170+
#
171+
# })
172+
#
173+
# depends_on = [null_resource.break_policy]
174+
#}
175+
176+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
output "environment_variables" {
2+
description = "Environment variables to be added to the IDE shell"
3+
value = merge({
4+
VPC_ID = data.aws_vpc.selected.id,
5+
LOAD_BALANCER_CONTROLLER_ROLE_NAME = module.eks_blueprints_addons.aws_load_balancer_controller.iam_role_name,
6+
LOAD_BALANCER_CONTROLLER_POLICY_ARN_FIX = module.eks_blueprints_addons.aws_load_balancer_controller.iam_policy_arn,
7+
LOAD_BALANCER_CONTROLLER_POLICY_ARN_ISSUE = aws_iam_policy.issue.arn,
8+
LOAD_BALANCER_CONTROLLER_ROLE_ARN = module.eks_blueprints_addons.aws_load_balancer_controller.iam_role_arn
9+
}, {
10+
for index, id in data.aws_subnets.public.ids : "PUBLIC_SUBNET_${index + 1}" => id
11+
}
12+
)
13+
}
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
#!/usr/bin/env bash
2+
#. .env
3+
4+
set -e
5+
6+
mkdir -p /eks-workshop/logs
7+
log_file=/eks-workshop/logs/action-$(date +%s).log
8+
9+
exec 2>&1
10+
11+
logmessage() {
12+
echo "$@" >&7
13+
echo "$@" >&1
14+
}
15+
export -f logmessage
16+
17+
# Function to get the role name from a role ARN
18+
get_role_name_from_arn() {
19+
local role_arn=$1
20+
21+
# Extract the role name from the ARN
22+
role_name=$(logmessage "$role_arn" | awk -F'/' '{print $NF}')
23+
24+
if [ -n "$role_name" ]; then
25+
logmessage "$role_name"
26+
else
27+
logmessage "Failed to retrieve role name from ARN: $role_arn"
28+
return 1
29+
fi
30+
}
31+
32+
# Function to get the Kubernetes role attached to a service account
33+
get_service_account_role() {
34+
local namespace=$1
35+
local service_account=$2
36+
37+
# Get the role ARN associated with the service account
38+
role_arn=$(kubectl get serviceaccount "$service_account" -n "$namespace" -o jsonpath="{.metadata.annotations['eks\.amazonaws\.com\/role-arn']}")
39+
40+
if [ -n "$role_arn" ]; then
41+
logmessage "Service Account: $service_account"
42+
logmessage "Namespace: $namespace"
43+
logmessage "Role ARN: $role_arn"
44+
get_role_name_from_arn "$role_arn"
45+
return 0
46+
else
47+
logmessage "Failed to retrieve role for service account '$service_account' in namespace '$namespace'"
48+
return 1
49+
fi
50+
51+
}
52+
53+
# Function to get the first policy ARN attached to a role ARN
54+
get_first_policy_arn_from_role_arn() {
55+
local role_arn=$1
56+
57+
# Get the list of policies attached to the role
58+
policy_arn=$(aws iam list-attached-role-policies --role-name "$role_arn" --query 'AttachedPolicies[0].PolicyArn' --output text)
59+
60+
if [ -n "$policy_arn" ]; then
61+
logmessage "First Policy ARN attached to role '$role_arn':"
62+
logmessage "Policy: $policy_arn"
63+
return 0
64+
else
65+
logmessage "Failed to retrieve policy ARN for role '$role_arn'"
66+
return 1
67+
fi
68+
}
69+
70+
# Function to update the policy with new statement
71+
update_policy_with_new_statement() {
72+
local policy_arn=$1
73+
local new_statement=$2
74+
75+
logmessage "PolicyARN: $policy_arn"
76+
logmessage "Statement: $new_statement"
77+
aws iam create-policy-version --policy-arn $policy_arn --policy-document $new_statement --set-as-default
78+
79+
}
80+
81+
# Function to remove an action from a policy statement
82+
remove_action_from_policy_statement() {
83+
local policy_name=$1
84+
local action_to_remove=$2
85+
86+
# Get the current policy document
87+
policy_document=$(aws iam get-policy-version --policy-arn "$policy_arn" --query 'PolicyVersion.Document' --version-id v1 --output json)
88+
89+
# Remove the specified action from the statements
90+
new_statements=$(logmessage "$policy_document" | jq ".Statement[] | select(.Action[] | contains('$action_to_remove')) | .Action = [.Action[] | select(. != '$action_to_remove')]")
91+
new_policy_document=$(logmessage '{"Version": "2012-10-17", "Statement": '"$new_statements"'}')
92+
+
93+
# Update the policy with the modified document
94+
logmessage "Policy Document"
95+
logmessage $new_policy_document
96+
#aws iam create-policy-version --policy-arn "$policy_arn" --policy-document "$new_policy_document" --set-as-default
97+
98+
if [ $? -eq 0 ]; then
99+
logmessage "Action removed from policy statement successfully."
100+
return 0
101+
else
102+
logmessage "Failed to remove action from policy statement."
103+
return 1
104+
fi
105+
}
106+
107+
# Function to remove tags from subnets ids
108+
remove_tags_from_subnets() {
109+
local tag_key="Key=kubernetes.io/role/elb,Value=1"
110+
111+
logmessage "retrive subnets ids with tag key assigned to specific vpc_id via aws cli"
112+
logmessage "getting public subnets from VPC: $vpc_id "
113+
114+
115+
subnets_vpc=$(aws ec2 describe-subnets --filters "Name=vpc-id,Values=$vpc_id" --query 'Subnets[*].SubnetId' --output text)
116+
logmessage "subnets_vpc: $subnets_vpc"
117+
118+
119+
#remove tag from subnets with AWS cli
120+
for subnet_id in $subnets_vpc; do
121+
logmessage "public subnets: $subnet_id"
122+
aws ec2 delete-tags --resources "$subnet_id" --tags "Key=$tag_key" || logmessage "Failed to remove tag from subnet $subnet_id"
123+
done
124+
return 0
125+
}
126+
127+
# Getting the service role
128+
path_tofile=$1
129+
mode=$2
130+
vpc_id=$3
131+
public_subnets=$4
132+
namespace="kube-system"
133+
service_account="aws-load-balancer-controller-sa"
134+
#new_statement="file://$path_tofile/template/iam_policy_incorrect.json"
135+
new_statement="file://$path_tofile/template/other_issue.json"
136+
137+
logmessage "path_sent: $path_tofile"
138+
139+
140+
# validate if mode is equal to mod1
141+
logmessage "mode: $mode"
142+
if [ "$mode" == "mod1" ]; then
143+
logmessage "Removing subnet tags"
144+
remove_tags_from_subnets
145+
else
146+
logmessage "Removing permissions"
147+
get_service_account_role "$namespace" "$service_account"
148+
get_first_policy_arn_from_role_arn "$role_name"
149+
update_policy_with_new_statement "$policy_arn" "$new_statement"
150+
151+
fi
152+
153+
154+
155+

0 commit comments

Comments
 (0)