Skip to content

Commit a70d7e2

Browse files
authored
Merge pull request #1603 from powerkimhub/feature/eks-role-name-refactor-create-if-missing
[AWS:K8S] Refactor EKS role names and create roles if missing
2 parents f84cfaf + 32764bf commit a70d7e2

File tree

1 file changed

+231
-9
lines changed

1 file changed

+231
-9
lines changed

cloud-control-manager/cloud-driver/drivers/aws/resources/ClusterHandler.go

Lines changed: 231 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,14 @@ func (ClusterHandler *AwsClusterHandler) CreateCluster(clusterReqInfo irs.Cluste
104104
}
105105

106106
//AWS의 경우 사전에 Role의 생성이 필요하며, 현재는 role 이름을 다음 이름으로 일치 시킨다.(추후 개선)
107-
//예시) cluster : cloud-barista-spider-eks-cluster-role, Node : cloud-barista-spider-eks-nodegroup-role
108-
eksRoleName := "cloud-barista-spider-eks-cluster-role"
109-
// get Role Arn
110-
eksRole, err := ClusterHandler.getRole(irs.IID{SystemId: eksRoleName})
107+
//예시) cluster : cloud-barista-eks-cluster-role, Node : cloud-barista-eks-nodegroup-role
108+
eksRoleName := "cloud-barista-eks-cluster-role"
109+
// get or create Role Arn
110+
eksRole, err := ClusterHandler.getOrCreateEKSClusterRole(eksRoleName)
111111
if err != nil {
112112
cblogger.Error(err)
113113
// role 은 required 임.
114-
return irs.ClusterInfo{}, err
114+
return irs.ClusterInfo{}, fmt.Errorf("failed to get or create EKS cluster role: %w", err)
115115
}
116116
roleArn := eksRole.Role.Arn
117117

@@ -742,13 +742,13 @@ func (ClusterHandler *AwsClusterHandler) AddNodeGroup(clusterIID irs.IID, nodeGr
742742
return irs.NodeGroupInfo{}, awserr.New(CUSTOM_ERR_CODE_BAD_REQUEST, "The MaxNodeSize value must be greater than or equal to 1.", nil)
743743
}
744744

745-
// get Role Arn
746-
eksRoleName := "cloud-barista-spider-eks-nodegroup-role"
747-
eksRole, err := ClusterHandler.getRole(irs.IID{SystemId: eksRoleName})
745+
// get or create Role Arn
746+
eksRoleName := "cloud-barista-eks-nodegroup-role"
747+
eksRole, err := ClusterHandler.getOrCreateEKSNodeGroupRole(eksRoleName)
748748
if err != nil {
749749
cblogger.Error(err)
750750
// role 은 required 임.
751-
return irs.NodeGroupInfo{}, err
751+
return irs.NodeGroupInfo{}, fmt.Errorf("failed to get or create EKS node group role: %w", err)
752752
}
753753
roleArn := eksRole.Role.Arn
754754

@@ -1471,6 +1471,228 @@ func (ClusterHandler *AwsClusterHandler) getRole(role irs.IID) (*iam.GetRoleOutp
14711471
return result, nil
14721472
}
14731473

1474+
// getOrCreateEKSClusterRole gets or creates EKS cluster role if it doesn't exist
1475+
func (ClusterHandler *AwsClusterHandler) getOrCreateEKSClusterRole(roleName string) (*iam.GetRoleOutput, error) {
1476+
cblogger.Infof("Getting or creating EKS cluster role: %s", roleName)
1477+
1478+
// Try to get existing role (without logging error if not found)
1479+
input := &iam.GetRoleInput{
1480+
RoleName: aws.String(roleName),
1481+
}
1482+
1483+
result, err := ClusterHandler.Iam.GetRole(input)
1484+
if err == nil {
1485+
cblogger.Infof("EKS cluster role already exists: %s", roleName)
1486+
return result, nil
1487+
}
1488+
1489+
// Check if error is NoSuchEntityException
1490+
if aerr, ok := err.(awserr.Error); ok {
1491+
if aerr.Code() != iam.ErrCodeNoSuchEntityException {
1492+
// Log error only if it's not NoSuchEntityException
1493+
cblogger.Error(aerr.Error())
1494+
return nil, fmt.Errorf("failed to get role: %w", err)
1495+
}
1496+
// NoSuchEntityException is expected, don't log as error
1497+
cblogger.Debugf("Role %s does not exist, will create it", roleName)
1498+
} else {
1499+
cblogger.Error(err.Error())
1500+
return nil, fmt.Errorf("failed to get role: %w", err)
1501+
}
1502+
1503+
// Role doesn't exist, create it
1504+
cblogger.Infof("Creating EKS cluster role: %s", roleName)
1505+
err = ClusterHandler.createEKSClusterRole(roleName)
1506+
if err != nil {
1507+
return nil, fmt.Errorf("failed to create EKS cluster role: %w", err)
1508+
}
1509+
1510+
// Get the newly created role
1511+
result, err = ClusterHandler.Iam.GetRole(input)
1512+
if err != nil {
1513+
return nil, fmt.Errorf("failed to get newly created role: %w", err)
1514+
}
1515+
1516+
cblogger.Infof("Successfully created and retrieved EKS cluster role: %s", roleName)
1517+
return result, nil
1518+
}
1519+
1520+
// getOrCreateEKSNodeGroupRole gets or creates EKS node group role if it doesn't exist
1521+
func (ClusterHandler *AwsClusterHandler) getOrCreateEKSNodeGroupRole(roleName string) (*iam.GetRoleOutput, error) {
1522+
cblogger.Infof("Getting or creating EKS node group role: %s", roleName)
1523+
1524+
// Try to get existing role (without logging error if not found)
1525+
input := &iam.GetRoleInput{
1526+
RoleName: aws.String(roleName),
1527+
}
1528+
1529+
result, err := ClusterHandler.Iam.GetRole(input)
1530+
if err == nil {
1531+
cblogger.Infof("EKS node group role already exists: %s", roleName)
1532+
return result, nil
1533+
}
1534+
1535+
// Check if error is NoSuchEntityException
1536+
if aerr, ok := err.(awserr.Error); ok {
1537+
if aerr.Code() != iam.ErrCodeNoSuchEntityException {
1538+
// Log error only if it's not NoSuchEntityException
1539+
cblogger.Error(aerr.Error())
1540+
return nil, fmt.Errorf("failed to get role: %w", err)
1541+
}
1542+
// NoSuchEntityException is expected, don't log as error
1543+
cblogger.Debugf("Role %s does not exist, will create it", roleName)
1544+
} else {
1545+
cblogger.Error(err.Error())
1546+
return nil, fmt.Errorf("failed to get role: %w", err)
1547+
}
1548+
1549+
// Role doesn't exist, create it
1550+
cblogger.Infof("Creating EKS node group role: %s", roleName)
1551+
err = ClusterHandler.createEKSNodeGroupRole(roleName)
1552+
if err != nil {
1553+
return nil, fmt.Errorf("failed to create EKS node group role: %w", err)
1554+
}
1555+
1556+
// Get the newly created role
1557+
result, err = ClusterHandler.Iam.GetRole(input)
1558+
if err != nil {
1559+
return nil, fmt.Errorf("failed to get newly created role: %w", err)
1560+
}
1561+
1562+
cblogger.Infof("Successfully created and retrieved EKS node group role: %s", roleName)
1563+
return result, nil
1564+
}
1565+
1566+
// createEKSClusterRole creates IAM role for EKS cluster with required policies
1567+
func (ClusterHandler *AwsClusterHandler) createEKSClusterRole(roleName string) error {
1568+
cblogger.Infof("Creating EKS cluster role: %s", roleName)
1569+
1570+
// Trust policy for EKS service
1571+
trustPolicy := `{
1572+
"Version": "2012-10-17",
1573+
"Statement": [
1574+
{
1575+
"Effect": "Allow",
1576+
"Principal": {
1577+
"Service": "eks.amazonaws.com"
1578+
},
1579+
"Action": "sts:AssumeRole"
1580+
}
1581+
]
1582+
}`
1583+
1584+
// Create role
1585+
createRoleInput := &iam.CreateRoleInput{
1586+
RoleName: aws.String(roleName),
1587+
AssumeRolePolicyDocument: aws.String(trustPolicy),
1588+
Description: aws.String("IAM role for Cloud-Barista EKS cluster"),
1589+
Tags: []*iam.Tag{
1590+
{
1591+
Key: aws.String("ManagedBy"),
1592+
Value: aws.String("Cloud-Barista-Spider"),
1593+
},
1594+
},
1595+
}
1596+
1597+
_, err := ClusterHandler.Iam.CreateRole(createRoleInput)
1598+
if err != nil {
1599+
cblogger.Errorf("Failed to create role: %v", err)
1600+
return fmt.Errorf("failed to create role: %w", err)
1601+
}
1602+
1603+
cblogger.Infof("Successfully created role: %s", roleName)
1604+
1605+
// Attach required policy: AmazonEKSClusterPolicy
1606+
policyArn := "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
1607+
attachPolicyInput := &iam.AttachRolePolicyInput{
1608+
RoleName: aws.String(roleName),
1609+
PolicyArn: aws.String(policyArn),
1610+
}
1611+
1612+
_, err = ClusterHandler.Iam.AttachRolePolicy(attachPolicyInput)
1613+
if err != nil {
1614+
cblogger.Errorf("Failed to attach policy %s: %v", policyArn, err)
1615+
return fmt.Errorf("failed to attach policy %s: %w", policyArn, err)
1616+
}
1617+
1618+
cblogger.Infof("Successfully attached policy %s to role %s", policyArn, roleName)
1619+
1620+
// Wait a bit for IAM changes to propagate
1621+
cblogger.Info("Waiting for IAM changes to propagate...")
1622+
time.Sleep(10 * time.Second)
1623+
1624+
return nil
1625+
}
1626+
1627+
// createEKSNodeGroupRole creates IAM role for EKS node group with required policies
1628+
func (ClusterHandler *AwsClusterHandler) createEKSNodeGroupRole(roleName string) error {
1629+
cblogger.Infof("Creating EKS node group role: %s", roleName)
1630+
1631+
// Trust policy for EC2 service
1632+
trustPolicy := `{
1633+
"Version": "2012-10-17",
1634+
"Statement": [
1635+
{
1636+
"Effect": "Allow",
1637+
"Principal": {
1638+
"Service": "ec2.amazonaws.com"
1639+
},
1640+
"Action": "sts:AssumeRole"
1641+
}
1642+
]
1643+
}`
1644+
1645+
// Create role
1646+
createRoleInput := &iam.CreateRoleInput{
1647+
RoleName: aws.String(roleName),
1648+
AssumeRolePolicyDocument: aws.String(trustPolicy),
1649+
Description: aws.String("IAM role for Cloud-Barista EKS node group"),
1650+
Tags: []*iam.Tag{
1651+
{
1652+
Key: aws.String("ManagedBy"),
1653+
Value: aws.String("Cloud-Barista-Spider"),
1654+
},
1655+
},
1656+
}
1657+
1658+
_, err := ClusterHandler.Iam.CreateRole(createRoleInput)
1659+
if err != nil {
1660+
cblogger.Errorf("Failed to create role: %v", err)
1661+
return fmt.Errorf("failed to create role: %w", err)
1662+
}
1663+
1664+
cblogger.Infof("Successfully created role: %s", roleName)
1665+
1666+
// Attach required policies
1667+
requiredPolicies := []string{
1668+
"arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy",
1669+
"arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy",
1670+
"arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryPullOnly",
1671+
"arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy",
1672+
}
1673+
1674+
for _, policyArn := range requiredPolicies {
1675+
attachPolicyInput := &iam.AttachRolePolicyInput{
1676+
RoleName: aws.String(roleName),
1677+
PolicyArn: aws.String(policyArn),
1678+
}
1679+
1680+
_, err = ClusterHandler.Iam.AttachRolePolicy(attachPolicyInput)
1681+
if err != nil {
1682+
cblogger.Errorf("Failed to attach policy %s: %v", policyArn, err)
1683+
return fmt.Errorf("failed to attach policy %s: %w", policyArn, err)
1684+
}
1685+
1686+
cblogger.Infof("Successfully attached policy %s to role %s", policyArn, roleName)
1687+
}
1688+
1689+
// Wait a bit for IAM changes to propagate
1690+
cblogger.Info("Waiting for IAM changes to propagate...")
1691+
time.Sleep(10 * time.Second)
1692+
1693+
return nil
1694+
}
1695+
14741696
/*
14751697
EKS의 NodeGroup정보를 Spider의 NodeGroup으로 변경
14761698
*/

0 commit comments

Comments
 (0)