Date: October 01, 2022
Dashboard app with Go AWS SDK
Motivation
- EC2 -> ECS ์ด๊ด ๋ฐ ์์ฑ ์์ ์ ํ์ํ, ECS, TG, ALB ๋ฑ ์์์กฐํ ๊ธฐ๋ฅ ํ์
- ์์ ์์ฑ ์ stage ๋ณ ๋ฐ์ดํฐ ํ์ธ ํ์ํ์ฌ AWS Console ๋์ , SDK ํ์ฉ
- CLI (go cobra library) ํด ๋์ , ์นํ์ด์ง url (ip:port)๋ก ๊ฐํธํ๊ฒ ์ฌ์ฉํ ์ ์๋ web ์ดํ๋ฆฌ์ผ์ด์
์์ฑ
- url: ํ๋ผ์ด๋น ํด๋ผ์ฐ๋ ๋ด๋ถ vpn์ผ๋ก๋ง ์ ๊ทผ ๊ฐ๋ฅ
- AWS ์์๊ฐ ์์กด์ฑ์ด ์๋๋ฐ, AWS๊ฐ ์ ๊ณตํ๋ ๋จ์ผ API๋ก ์ํ๋ ์์์ํ ์กฐํ๊ฐ ํ๋ฆ
- AWS API ํธ์ถ ๊ฒฐ๊ณผ๋ค๋ก object list ๋ง๋ค์ด, ์ ๋ ฌ ์ฒ๋ฆฌ (Override Len, Less, Swap functions)
Skills
Backend : Go, Go AWS SDK
Frontend : Javascript, HTML, CSS
How Application Works
It utilizes Go AWS SDK to render a organized view of AWS resources deployed in multiple environments: dev, stg, prd.
- ALB > TargetGroup > Target Health > Container_Ip, Instance_Id
- ECS Task์ Container, Image, IP ๋ฑ
- ECR tag, image uri -> ์ต์ ์ ์ ๋ ฌ
Progress
- Web application (go, javascript, html, css) ์์ฑ
- ์ปจํ
์ด๋ํ
- Dockerfile ๋น๋, Image ์์ฑ, ์ปจํ ์ด๋ Run
- EC2 role based access๋ก, aws credential ๊ด๋ฆฌ -> ๋์ปค ์ปจํ ์ด๋๋ก credential propagation ํ ์คํธ ์ค
- ๊ณ ๋ฃจํด ๋ฐ ์ฑ๋ ์ ์ฉ: API ํธ์ถ์ ๋ค์์ AWS api ํต์ ํ๋ ๊ฒฝ์ฐ
- Cloudwatch ๋ก๊ทธ, EC2, Task event ์กฐํ(down, up) ์ถ๊ฐ ์์
Test
- Cloud์ ์ -> Vpn > http://{ip_addr}:port
Aws Profile Management
-
credential_source=Ec2InstanceMetadata
- AWS CLI / SDK๊ฐ EC2 ์ธ์คํด์ค์ attach๋ IAM Role ์ฌ์ฉํ์ฌ Source credential ๊ฐ์ ธ์ด
-
EC2์ธ์คํด์ค์ IAM Role Attachํ๊ธฐ
# IAM Role with permission policies :
# Create role > Add Permissions
AmazonEC2FullAccess
Provides full access to Amazon EC2 via the AWS Management Console.
IAMFullAccess
Provides full access to IAM via the AWS Management Console.
AmazonEC2ContainerRegistryFullAccess
Provides administrative access to Amazon ECR resources
AmazonS3FullAccess
Provides full access to all buckets via the AWS Management Console.
ReadOnlyAccess
Provides read-only access to AWS services and resources.
AmazonSESFullAccess
Provides full access to Amazon SES via the AWS Management Console.
AmazonAPIGatewayAdministrator
Provides full access to create/edit/delete APIs in Amazon API Gateway via the AWS Management Console.
AmazonECS_FullAccess
Provides administrative access to Amazon ECS resources and enables ECS features through access to other AWS service resources, including VPCs, Auto Scaling groups, and CloudFormation stacks.
AWSCloudFormationFullAccess
Provides full access to AWS CloudFormation.
AWSLambda_FullAccess
Grants full access to AWS Lambda service, AWS
Credential: go aws sdk
import "github.com/aws/aws-sdk-go/aws/session"
// AWS ํ๋กํ์ผ ๋ช
(~/.aws/config)
type AwsProfile struct{
dev string
stg string
prd string
}
var awsProfile AwsProfile
// ์ธ์
๊ฐ์ฒด ์ด๊ธฐํ
func InitSession(profile string) *session.Session {
if profile == "dev" {
profile = awsProfile.dev
} else if profile == "stg" {
profile = awsProfile.stg
} else if profile == "prd" {
profile = awsProfile.prd
}
sess, err := session.NewSessionWithOptions(session.Options{
// Specify profile to load for the session's config
Profile: profile,
SharedConfigState: session.SharedConfigEnable,
})
if err != nil {
panic(err)
}
return sess
}
Repo custom interface
func (repo *Repo) getAWSTargetGroups()
func (repo *Repo) getAWSTargetHealths(tgarn string)
func (repo *Repo) getAWSEcsClusterDetails(clusterArn string)
func (repo *Repo) getAWSEcsSvcList(clusterArns []*string)
func (repo *Repo) getAWSListClusters()
func (repo *Repo) getAWSEcsClusters(clusters []*string)
func (repo *Repo) getAWSEcsDescribeTaskDefinition(services []*ecs.Service)
func (repo *Repo) getAWSEcsListAndDescribeTasks(clusterName, serviceName string)
func (repo *Repo) getAWSEcsDescribeService(clusterName, serviceName string)
func (repo *Repo) getAWSEcrRepos(repoName string)
func (repo *Repo) getAWSEcrDescribeImages(repoUri, repoName string)
// ์ธ์
๋ฆฌํฌ์งํ ๋ฆฌ
type Repo struct {
sess *session.Session
}
// ์ธ์
๋ฆฌํฌ์งํ ๋ฆฌ ์ธํฐํ์ด์ค
func RepoInterface(param *session.Session) *Repo {
return &Repo{sess: param}
}
/**
* ์ธ์
๋ฆฌํฌ์งํ ๋ฆฌ Repo ๊ตฌํ์ฒด
*/
// TG ์กฐํ -> tgMap ์ ์ฅ
func (repo *Repo) getAWSTargetGroups() {
// ๋ฐ์ดํฐ ์ด๊ธฐํ
tgMap = make(map[string]*elbv2.TargetGroup)
// ELBV2 ์๋น์ค ์์ฑ
svc := elbv2.New(repo.sess)
input := &elbv2.DescribeTargetGroupsInput{ // ์์ฒญ ํ๋ผ๋ฏธํฐ
Names: []*string {
// aws.String("awsdc-tg-erp-dev-tdms-7080"),
},
}
// ELBV2 ์๋น์ค api DescribeTargetGroups ํธ์ถ
pageNum := 0
// result, err := svc.DescribeTargetGroups(input)
err := svc.DescribeTargetGroupsPages(input, func(page *elbv2.DescribeTargetGroupsOutput, lastPage bool) bool {
pageNum++
log.Println("PAGE result data size: ", len(page.TargetGroups))
for _, tg := range page.TargetGroups {
tgMap[*tg.TargetGroupName] = tg
}
return !lastPage
})
if err != nil {
handleError(err)
return
}
}