Skip to content

Commit 2170097

Browse files
authored
feat: add initial code for cloudformation and aws (#11)
1 parent e371dfe commit 2170097

File tree

5 files changed

+269
-6
lines changed

5 files changed

+269
-6
lines changed

README.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,99 @@ mise task run "delete:k3d:*"
1919

2020
> Same for eksctl, az, terraform-aws, terraform-az, ... clusters
2121
22+
## Architecture diagrams
23+
24+
### DNS diagram
25+
26+
```mermaid
27+
flowchart TB
28+
subgraph "Cloudflare"
29+
mylabs.dev@{ icon: "logos:cloudflare-icon", form: "square", label: "mylabs.dev", pos: "b", h: 60 }
30+
end
31+
32+
subgraph "AWS"
33+
subgraph "AWS Primary Account"
34+
aws.mylabs.dev@{ icon: "logos:aws-route53", form: "circle", label: "aws.mylabs.dev", pos: "b", h: 60 }
35+
k8s.aws.mylabs.dev@{ icon: "logos:aws-route53", form: "square", label: "k8s.aws.mylabs.dev", pos: "b", h: 60 }
36+
end
37+
subgraph "AWS Account 03"
38+
k05.k8s.aws.mylabs.dev@{ icon: "logos:aws-route53", form: "square", label: "k05.k8s.aws.mylabs.dev", pos: "b", h: 60 }
39+
k06.k8s.aws.mylabs.dev@{ icon: "logos:aws-route53", form: "square", label: "k06.k8s.aws.mylabs.dev", pos: "b", h: 60 }
40+
end
41+
subgraph "AWS Account 02"
42+
k03.k8s.aws.mylabs.dev@{ icon: "logos:aws-route53", form: "square", label: "k03.k8s.aws.mylabs.dev", pos: "b", h: 60 }
43+
k04.k8s.aws.mylabs.dev@{ icon: "logos:aws-route53", form: "square", label: "k04.k8s.aws.mylabs.dev", pos: "b", h: 60 }
44+
end
45+
subgraph "AWS Account 01"
46+
k01.k8s.aws.mylabs.dev@{ icon: "logos:aws-route53", form: "square", label: "k01.k8s.aws.mylabs.dev", pos: "b", h: 60 }
47+
k02.k8s.aws.mylabs.dev@{ icon: "logos:aws-route53", form: "square", label: "k02.k8s.aws.mylabs.dev", pos: "b", h: 60 }
48+
end
49+
end
50+
51+
subgraph "Azure"
52+
subgraph "Azure Primary Account"
53+
az.mylabs.dev@{ icon: "logos:azure-icon", form: "circle", label: "az.mylabs.dev", pos: "b", h: 60 }
54+
k8s.az.mylabs.dev@{ icon: "logos:azure-icon", form: "square", label: "k8s.az.mylabs.dev", pos: "b", h: 60 }
55+
end
56+
subgraph "Azure Account 03"
57+
k05.k8s.az.mylabs.dev@{ icon: "logos:azure-icon", form: "square", label: "k05.k8s.az.mylabs.dev", pos: "b", h: 60 }
58+
k06.k8s.az.mylabs.dev@{ icon: "logos:azure-icon", form: "square", label: "k06.k8s.az.mylabs.dev", pos: "b", h: 60 }
59+
end
60+
subgraph "Azure Account 02"
61+
k03.k8s.az.mylabs.dev@{ icon: "logos:azure-icon", form: "square", label: "k03.k8s.az.mylabs.dev", pos: "b", h: 60 }
62+
k04.k8s.az.mylabs.dev@{ icon: "logos:azure-icon", form: "square", label: "k04.k8s.az.mylabs.dev", pos: "b", h: 60 }
63+
end
64+
subgraph "Azure Account 01"
65+
k01.k8s.az.mylabs.dev@{ icon: "logos:azure-icon", form: "square", label: "k01.k8s.az.mylabs.dev", pos: "b", h: 60 }
66+
k02.k8s.az.mylabs.dev@{ icon: "logos:azure-icon", form: "square", label: "k02.k8s.az.mylabs.dev", pos: "b", h: 60 }
67+
end
68+
end
69+
70+
subgraph "GCP"
71+
subgraph "GCP Primary Account"
72+
gcp.mylabs.dev@{ icon: "logos:google-cloud", form: "circle", label: "gcp.mylabs.dev", pos: "b", h: 60 }
73+
k8s.gcp.mylabs.dev@{ icon: "logos:google-cloud", form: "square", label: "k8s.gcp.mylabs.dev", pos: "b", h: 60 }
74+
end
75+
subgraph "GCP Account 03"
76+
k05.k8s.gcp.mylabs.dev@{ icon: "logos:google-cloud", form: "square", label: "k05.k8s.gcp.mylabs.dev", pos: "b", h: 60 }
77+
k06.k8s.gcp.mylabs.dev@{ icon: "logos:google-cloud", form: "square", label: "k06.k8s.gcp.mylabs.dev", pos: "b", h: 60 }
78+
end
79+
subgraph "GCP Account 02"
80+
k03.k8s.gcp.mylabs.dev@{ icon: "logos:google-cloud", form: "square", label: "k03.k8s.gcp.mylabs.dev", pos: "b", h: 60 }
81+
k04.k8s.gcp.mylabs.dev@{ icon: "logos:google-cloud", form: "square", label: "k04.k8s.gcp.mylabs.dev", pos: "b", h: 60 }
82+
end
83+
subgraph "GCP Account 01"
84+
k01.k8s.gcp.mylabs.dev@{ icon: "logos:google-cloud", form: "square", label: "k01.k8s.gcp.mylabs.dev", pos: "b", h: 60 }
85+
k02.k8s.gcp.mylabs.dev@{ icon: "logos:google-cloud", form: "square", label: "k02.k8s.gcp.mylabs.dev", pos: "b", h: 60 }
86+
end
87+
end
88+
89+
mylabs.dev --> aws.mylabs.dev
90+
aws.mylabs.dev --> k8s.aws.mylabs.dev
91+
k8s.aws.mylabs.dev --> k01.k8s.aws.mylabs.dev
92+
k8s.aws.mylabs.dev --> k02.k8s.aws.mylabs.dev
93+
k8s.aws.mylabs.dev --> k03.k8s.aws.mylabs.dev
94+
k8s.aws.mylabs.dev --> k04.k8s.aws.mylabs.dev
95+
k8s.aws.mylabs.dev --> k05.k8s.aws.mylabs.dev
96+
k8s.aws.mylabs.dev --> k06.k8s.aws.mylabs.dev
97+
mylabs.dev --> az.mylabs.dev
98+
az.mylabs.dev --> k8s.az.mylabs.dev
99+
k8s.az.mylabs.dev --> k01.k8s.az.mylabs.dev
100+
k8s.az.mylabs.dev --> k02.k8s.az.mylabs.dev
101+
k8s.az.mylabs.dev --> k03.k8s.az.mylabs.dev
102+
k8s.az.mylabs.dev --> k04.k8s.az.mylabs.dev
103+
k8s.az.mylabs.dev --> k05.k8s.az.mylabs.dev
104+
k8s.az.mylabs.dev --> k06.k8s.az.mylabs.dev
105+
mylabs.dev --> gcp.mylabs.dev
106+
gcp.mylabs.dev --> k8s.gcp.mylabs.dev
107+
k8s.gcp.mylabs.dev --> k01.k8s.gcp.mylabs.dev
108+
k8s.gcp.mylabs.dev --> k02.k8s.gcp.mylabs.dev
109+
k8s.gcp.mylabs.dev --> k03.k8s.gcp.mylabs.dev
110+
k8s.gcp.mylabs.dev --> k04.k8s.gcp.mylabs.dev
111+
k8s.gcp.mylabs.dev --> k05.k8s.gcp.mylabs.dev
112+
k8s.gcp.mylabs.dev --> k06.k8s.gcp.mylabs.dev
113+
```
114+
22115
---
23116

24117
## Tests
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
AWSTemplateFormatVersion: 2010-09-09
2+
3+
Description: Route53 entry and IAM role for GitHub Actions OIDC federated role
4+
5+
Parameters:
6+
PrimaryDomain:
7+
Description: "Primary domain for AWS services (e.g. aws.mylabs.dev)"
8+
Type: String
9+
K8sDomain:
10+
Description: "K8s domain hosting cluster subdomains (e.g. k8s.aws.mylabs.dev)"
11+
Type: String
12+
# GithubActionsThumbprint:
13+
# Type: CommaDelimitedList
14+
# Default: 6938fd4d98bab03faadb97b34396831e3780aea1
15+
# Description: >
16+
# Comma seperated list of thumbprints for GitHub Actions tokens.
17+
# Default comes from https://github.blog/changelog/2022-01-13-github-actions-update-on-oidc-based-deployments-to-aws/
18+
# AudienceList:
19+
# Type: CommaDelimitedList
20+
# Default: sts.amazonaws.com
21+
# Description: >
22+
# Comma separated list of allowed audience for the tokens.
23+
# Default is audience for the official AWS configure action from https://github.com/aws-actions/configure-aws-credentials
24+
# SubjectClaimFilters:
25+
# Type: CommaDelimitedList
26+
# Default: "repo:ruzickap/k8s-multicluster-gitops:*"
27+
# Description: >
28+
# Subject claim filter for valid tokens.
29+
# Default allows any branch or tag of the McK-Internal/VM-wiz-automation to assume the role.
30+
# See https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#example-subject-claims
31+
# for examples of filtering by branch or deployment environment.
32+
# ManagedPolicyARNs:
33+
# Type: CommaDelimitedList
34+
# Default: arn:aws:iam::aws:policy/AdministratorAccess
35+
# Description: Comma separated list for arns for managed policies to attach to the role
36+
37+
Resources:
38+
PrimaryHostedZone:
39+
Type: AWS::Route53::HostedZone
40+
Properties:
41+
Name: !Ref PrimaryDomain
42+
HostedZoneConfig:
43+
Comment: Primary domain for AWS services
44+
K8sHostedZone:
45+
Type: AWS::Route53::HostedZone
46+
Properties:
47+
Name: !Ref K8sDomain
48+
HostedZoneConfig:
49+
Comment: K8s domain hosting cluster subdomains
50+
nsRootPrimaryHostedZoneRecordSet:
51+
Type: "AWS::Route53::RecordSet"
52+
Properties:
53+
HostedZoneId: !Ref PrimaryHostedZone
54+
Name: !Sub "${K8sDomain}."
55+
Type: NS
56+
TTL: 86400
57+
ResourceRecords: !GetAtt K8sHostedZone.NameServers
58+
# GitHubIdentityProvider:
59+
# Type: AWS::IAM::OIDCProvider
60+
# Properties:
61+
# ClientIdList: !Ref AudienceList
62+
# ThumbprintList: !Ref GithubActionsThumbprint
63+
# Url: https://token.actions.githubusercontent.com
64+
# GitHubActionsServiceRole:
65+
# Type: AWS::IAM::Role
66+
# Properties:
67+
# AssumeRolePolicyDocument:
68+
# Version: "2012-10-17"
69+
# Statement:
70+
# - Sid: RoleForGitHubActions
71+
# Effect: Allow
72+
# Principal:
73+
# Federated: !Ref GitHubIdentityProvider
74+
# Action:
75+
# - "sts:AssumeRoleWithWebIdentity"
76+
# Condition:
77+
# StringLike:
78+
# token.actions.githubusercontent.com:sub: !Ref SubjectClaimFilters
79+
# - Sid: AllowUsersToAssumeRole
80+
# Effect: Allow
81+
# Principal:
82+
# AWS: !GetAtt User.Arn
83+
# Action:
84+
# - "sts:AssumeRole"
85+
# Description: Service Role for use in GitHub Actions
86+
# RoleName: GitHubOidcFederatedRole
87+
# MaxSessionDuration: 36000
88+
# ManagedPolicyArns: !Ref ManagedPolicyARNs
89+
90+
# Outputs:
91+
# ServiceRoleARN:
92+
# Description: Arn of service role for use in GitHub actions
93+
# Value: !GetAtt GitHubActionsServiceRole.Arn

lychee.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ exclude = [
3636
'stackexchange\.com',
3737
# returns 403 when accessed from GitHub Action
3838
'stackoverflow\.com',
39+
'token\.actions\.githubusercontent\.com',
3940
# keep-sorted end
4041
]
4142

mise.toml

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
[tools]
22
# Tools need to be downloaded each time because if they were downloaded within 'tasks' (which run in parallel), the PATH propagation would not work properly.
33
# keep-sorted start
4+
aws = "2.24.24"
5+
eksctl = "0.205.0"
46
k3d = "5.8.3"
57
kind = "0.27.0"
68
# keep-sorted end
@@ -11,16 +13,20 @@ trusted_config_paths = ["/"]
1113
task_output = "prefix"
1214

1315
[env]
16+
AWS_PRIMARY_DOMAIN = "aws.mylabs.dev"
17+
AWS_K8S_DOMAIN = "k8s.{{ env.AWS_PRIMARY_DOMAIN }}"
1418
# keep-sorted start
19+
# Default AWS region if not overridden
20+
AWS_REGION = "us-east-1"
21+
CLICOLOR_FORCE = "1"
1522
# Directory which contains the clusters mise configurations
1623
CLUSTERS_DIRECTORY = "{{ config_root }}/clusters"
1724
# Directory which contains the kubeconfig files for the created clusters (will be create if not exists)
1825
CLUSTERS_KUBECONFIG_DIRECTORY = "{{ config_root }}/clusters/.kubeconfig"
1926
# Directory which contains the scripts to create and delete the clusters
2027
CLUSTERS_RUN_SCRIPT_DIRECTORY = "{{ config_root }}/scripts"
21-
CLICOLOR_FORCE = "1"
2228
MISE_TASK_OUTPUT = "prefix"
23-
# keep-sorted stop
29+
# keep-sorted end
2430

2531
[tasks."create-all"]
2632
description = 'Create all K8s clusters'
@@ -32,9 +38,47 @@ confirm = 'Are you sure you want to delete all K8s clusters created by mise?'
3238
# Do not use 'depends = ["delete:*:*"]' because it will run before question above
3339
run = 'mise run "delete:*:*"'
3440

35-
#######################################
41+
##############################################################################
42+
# Primary AWS Account - CloudFormation - Route53 + GitHub Actions Access + IAM role
43+
##############################################################################
44+
45+
[tasks."create:aws-primary:cf-route53-gh-action-iam-role-oidc"]
46+
description = 'Configure Primary AWS Account - Create CloudFormation - Route53 + GitHub Actions Access + IAM role'
47+
confirm = '''
48+
Make sure you have the following AWS environment variables set for your "Primary AWS account":
49+
- AWS_ACCESS_KEY_ID
50+
- AWS_SECRET_ACCESS_KEY
51+
- AWS_SESSION_TOKEN - in case you are using temporary credentials
52+
'''
53+
env.GIT_REPOSITORY = "{{ exec(command='git config --get remote.origin.url') }}"
54+
env.AWS_CLOUDFORMATION_TEMPLATE_FILE = "cloudformation/aws-cf-route53-gh-action-iam-role-oidc.yml"
55+
run = '''
56+
eval aws cloudformation deploy --capabilities CAPABILITY_NAMED_IAM \
57+
--stack-name route53-gh-action-iam-role-oidc \
58+
--parameter-overrides "PrimaryDomain=${AWS_PRIMARY_DOMAIN} K8sDomain=${AWS_K8S_DOMAIN}" \
59+
--template-file "${AWS_CLOUDFORMATION_TEMPLATE_FILE}" \
60+
--tags "git_repository=${GIT_REPOSITORY}//${AWS_CLOUDFORMATION_TEMPLATE_FILE}"
61+
'''
62+
63+
[tasks."delete:aws-primary:cf-route53-gh-action-iam-role-oidc"]
64+
description = 'Primary AWS Account - Delete CloudFormation - Route53 + GitHub Actions Access + IAM role'
65+
confirm = '''
66+
Are you sure you want to delete the CloudFormation (Route53 + GitHub Actions Access + IAM role) from Primary AWS Account?
67+
68+
Make sure you have the following AWS environment variables set for your "Primary AWS account":
69+
- AWS_ACCESS_KEY_ID
70+
- AWS_SECRET_ACCESS_KEY
71+
- AWS_SESSION_TOKEN - in case you are using temporary credentials
72+
'''
73+
74+
run = '''
75+
aws cloudformation delete-stack --stack-name route53-gh-action-iam-role-oidc
76+
aws cloudformation wait stack-delete-complete --stack-name route53-gh-action-iam-role-oidc
77+
'''
78+
79+
##############################################################################
3680
# Kind
37-
#######################################
81+
##############################################################################
3882

3983
[tasks."create:kind:kind01-internal"]
4084
description = 'Create kind01.internal K8s cluster'
@@ -61,9 +105,9 @@ run = 'mise run "create:kind:*"'
61105
description = 'Delete kind K8s clusters'
62106
run = 'mise run "delete:kind:*"'
63107

64-
#######################################
108+
##############################################################################
65109
# K3d
66-
#######################################
110+
##############################################################################
67111

68112
[tasks."create:k3d:k3d01-internal"]
69113
description = 'Create k3d01.internal K8s cluster'
@@ -89,3 +133,23 @@ run = 'mise run "create:k3d:*"'
89133
[tasks."delete-k3d-all"]
90134
description = 'Delete k3d K8s clusters'
91135
run = 'mise run "delete:k3d:*"'
136+
137+
##############################################################################
138+
# eksctl
139+
##############################################################################
140+
141+
[tasks."create:eksctl:k01-k8s-aws-mylabs-dev"]
142+
description = 'Create k01.k8s.aws.mylabs.dev K8s cluster'
143+
run = 'mise run --env ${MISE_TASK_NAME##*:} create:${MISE_TASK_NAME##*:}'
144+
145+
[tasks."delete:eksctl:k01-k8s-aws-mylabs-dev"]
146+
description = 'Delete k01.k8s.aws.mylabs.dev K8s cluster'
147+
run = 'mise run --env ${MISE_TASK_NAME##*:} delete:${MISE_TASK_NAME##*:}'
148+
149+
[tasks."create-eksctl-all"]
150+
description = 'Create eksctl K8s clusters'
151+
run = 'mise run "create:eksctl:*"'
152+
153+
[tasks."delete-eksctl-all"]
154+
description = 'Delete eksctl K8s clusters'
155+
run = 'mise run "delete:eksctl:*"'
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[env]
2+
CLUSTER_FQDN = "k01.k8s.aws.mylabs.dev"
3+
BASE_DOMAIN = '{{ env.CLUSTER_FQDN | split(pat=".") | slice(start=1) | join(sep=".") }}'
4+
CLUSTER_NAME = '{{ env.CLUSTER_FQDN | split(pat=".") | first }}'
5+
6+
[tasks."create:k01-k8s-aws-mylabs-dev"]
7+
description = 'Create K8s cluster'
8+
run = '${CLUSTERS_RUN_SCRIPT_DIRECTORY}/run-eksctl.sh create'
9+
10+
[tasks."delete:k01-k8s-aws-mylabs-dev"]
11+
description = 'Delete K8s cluster'
12+
run = '${CLUSTERS_RUN_SCRIPT_DIRECTORY}/run-eksctl.sh delete'

0 commit comments

Comments
 (0)