version: 0.2
env:
exported-variables: #내보낼 환경 변수 지정합니다.
- AWS_DEFAULT_REGION
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws --version
- aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-2.amazonaws.com
- REPOSITORY_URI=$AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-2.amazonaws.com/wsi-fargate-ecr-repo
- COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
- IMAGE_TAG=${COMMIT_HASH:=latest}
build:
commands:
- echo Build started on `date`
- echo Building the Docker image...
- docker build -t $REPOSITORY_URI\:latest .
- docker tag $REPOSITORY_URI\:latest $REPOSITORY_URI:$IMAGE_TAG
post_build:
commands:
- docker push $REPOSITORY_URI\:latest
- docker push $REPOSITORY_URI:$IMAGE_TAG
- echo Writing image definitions file...
- printf '[{"name":"wsi-rolling-deploy","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
- printf '{"ImageURI":"%s"}' $REPOSITORY_URI:$IMAGE_TAG > imageDetail.json
artifacts:
files:
- imagedefinitions.json
- imageDetail.json
- appspec.yml
- taskdef.json
secondary-artifacts:
DefinitionArtifact:
files:
- appspec.yml
- taskdef.json
ImageArtifact:
files:
- imageDetail.json
version: 0.2
phases:
pre_build:
commands:
- echo $AWS_DEFAULT_REGION
- aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-2.amazonaws.com
- REPOSITORY_NAME="wsi-ecr-repo"
- REPOSITORY_URI=$AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-2.amazonaws.com/$REPOSITORY_NAME
- COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
- IMAGE_TAG=${COMMIT_HASH:=latest}
build:
commands:
- echo Building the Docker image...
- docker build -t wsi-ecr-repo:latest .
- docker tag wsi-ecr-repo:latest $AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-2.amazonaws.com/wsi-ecr-repo:latest
- docker tag $REPOSITORY_NAME:latest $REPOSITORY_URI:$IMAGE_TAG
post_build:
commands:
- docker push $REPOSITORY_URI:latest
- docker push $REPOSITORY_URI:$IMAGE_TAG
- printf '[{"name":"golang-container","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
- OLD=$AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-2.amazonaws.com/eks-ecr-repo:7808f41
- ECRREPO=$REPOSITORY_URI:$IMAGE_TAG
- sed -i "s|$OLD|$ECRREPO|g" taskdefintion.json
- sed -i s/AWS_DEFAULT_REGION/$AWS_DEFAULT_REGION/ appspec.yaml
- sed -i s/AWS_ACCOUNT_ID/$AWS_ACCOUNT_ID/ appspec.yaml
- sed -i s/TASK_NAME/$TASK_NAME/ appspec.yaml
- sed -i s/CONTAINER_NAME/$CONTAINER_NAME/ appspec.yaml
- sed -i s/CONTAINER_PORT/$CONTAINER_PORT/ appspec.yaml
artifacts:
files:
- imagedefinitions.json
- imagedefinitions.json
- appspec.yml
- taskdefintion.json
version: 0.2
phases:
pre_build:
commands:
- echo $AWS_DEFAULT_REGION
- aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 680360122082.dkr.ecr.ap-northeast-2.amazonaws.com
- REPOSITORY_NAME="wsi-ecr-repo"
- REPOSITORY_URI=680360122082.dkr.ecr.ap-northeast-2.amazonaws.com/$REPOSITORY_NAME
- COMMIT_HASH=$(date +"%y%m%d%H%M%S")
- IMAGE_TAG=${COMMIT_HASH:=latest}
build:
commands:
- echo Building the Docker image...
- docker build -t wsi-ecr-repo:latest .
- docker tag wsi-ecr-repo:latest 680360122082.dkr.ecr.ap-northeast-2.amazonaws.com/wsi-ecr-repo:latest
- docker tag $REPOSITORY_NAME:latest $REPOSITORY_URI:$IMAGE_TAG
post_build:
commands:
- docker push $REPOSITORY_URI:latest
- docker push $REPOSITORY_URI:$IMAGE_TAG
- printf '[{"name":"golang-container","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
- OLD=680360122082.dkr.ecr.ap-northeast-2.amazonaws.com/eks-ecr-repo:7808f41
- ECRREPO=$REPOSITORY_URI:$IMAGE_TAG
- sed -i "s|$OLD|$ECRREPO|g" taskdefintion.json
- sed -i s/AWS_DEFAULT_REGION/$AWS_DEFAULT_REGION/ appspec.yaml
- sed -i s/AWS_ACCOUNT_ID/$AWS_ACCOUNT_ID/ appspec.yaml
- sed -i s/TASK_NAME/$TASK_NAME/ appspec.yaml
- sed -i s/CONTAINER_NAME/$CONTAINER_NAME/ appspec.yaml
- sed -i s/CONTAINER_PORT/$CONTAINER_PORT/ appspec.yaml
artifacts:
files:
- imagedefinitions.json
- appspec.yml
- taskdefintion.json
Buildspec.yml 파일을 구성하실 때 꼭!!! 열을 제대로 맞춰야합니다. 구문이 조금이라도 틀리면 에러가 발생합니다.
version: 0.0
Resources:
- TargetService:
Type: AWS::ECS::Service
Properties:
TaskDefinition: <TASK_DEFINITION>
LoadBalancerInfo:
ContainerName: "wsi-fargate-containers"
ContainerPort: 8080
version: 0.0
Resources:
- TargetService:
Type: AWS::ECS::Service
Properties:
TaskDefinition: "arn:aws:ecs:AWS_DEFAULT_REGION:AWS_ACCOUNT_ID:task-definition/TASK_NAME"
LoadBalancerInfo:
ContainerName: "CONTAINER_NAME"
ContainerPort: CONTAINER_PORT
PlatformVersion: "LATEST"
NetworkConfiguration:
AwsvpcConfiguration:
Subnets: ["subnet-1234abcd","subnet-5678abcd"]
SecurityGroups: ["sg-12345678"]
AssignPublicIp: "DISABLED"
CapacityProviderStrategy:
- Base: 1 #Base는 용량 공급자에서 실행할 테스크 수를 지정합니다.
CapacityProviderA: "FARGATE_SPOT"
Weight: 1 #capacityProviderA에 1의 가중치를 지정하고 capacityProviderB에 4의 가중치를 지정하면 capacityProviderA를 사용하여 실행되는 모든 태스크에 대해 네 가지 태스크에서 capacityProviderB를 사용합니다.
- Base: 0
CapacityProviderB: "FARGATE"
Weight: 4
ECS Cluster를 Fargate 유형을 생성하면 용량 공급자가 2개가 기본적으로 생성됩니다
{
"family": "wsi-bluegreen-fargate-df",
"executionRoleArn": "arn:aws:iam::040217728499:role/ecsTaskExecutionRole",
"taskRoleArn": "arn:aws:iam::040217728499:role/ecsTaskExecutionRole",
"networkMode": "awsvpc",
"memory": "1024",
"cpu": "512",
"requiresCompatibilities": [
"FARGATE"
],
"containerDefinitions": [
{
"name": "wsi-fargate-containers",
"memoryReservation": 500,
"image": "<IMAGE_NAME>",
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/wsi-bluegreen-fargate-df",
"awslogs-region": "ap-northeast-2",
"awslogs-stream-prefix": "ecs"
}
},
"portMappings": [
{
"hostPort": 8080,
"protocol": "tcp",
"containerPort": 8080
}
],
"essential": true
}
]
}
JSON은 주석을 허용하지 않기때문에 여기에 JSON에서 중요한 점을 명시하도록 하겠습니다.
Role을 꼭 지정해합니다. 또한 LogGroup이 존재해야합니다.
또한 현재 Image는 <IMAGE_NAME>으로 지정했습니다. Pipeline에서 Blue/Green 배포할 때 왜 해주었는지 알게될 수 있습니다.
{
"family": "wsi-ecs-ec2-tf",
"networkMode": "bridge",
"memory": "256",
"executionRoleArn": "arn:aws:iam::040217728499:role/ecsTaskExecutionRole",
"requiresCompatibilities": [
"EC2"
],
"containerDefinitions": [
{
"name": "wsi-ec2-containerimages",
"image": "<IMAGE_NAME>",
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/wsi-ecs-ec2-tf",
"awslogs-region": "ap-northeast-2",
"awslogs-stream-prefix": "ecs"
}
},
"portMappings": [
{
"hostPort": 0,
"protocol": "tcp",
"containerPort": 8080
}
],
"essential": true
}
]
}
package main
import (
"fmt"
"log"
"net"
"net/http"
)
func main() {
log.Print("HTTPserver: Enter main()")
http.HandleFunc("/health", handler)
log.Fatal(http.ListenAndServe("0.0.0.0:8080", nil))
}
// printing request headers/params
func handler(w http.ResponseWriter, r *http.Request) {
log.Print("request from address: %q\n", r.RemoteAddr)
fmt.Fprintf(w, "%s %s %s\n", r.Method, r.URL, r.Proto)
fmt.Fprintf(w, "Host = %q\n", r.Host)
fmt.Fprintf(w, "RemoteAddr = %q\n", r.RemoteAddr)
if err := r.ParseForm(); err != nil {
log.Print(err)
}
for k, v := range r.Form {
fmt.Fprintf(w, "Form[%q] = %q\n", k, v)
}
fmt.Fprintf(w, "\n===> local IP: %q\n\n", GetOutboundIP())
}
func GetOutboundIP() net.IP {
conn, err := net.Dial("udp", "8.8.8.8:80")
if err != nil {
log.Fatal(err)
}
defer conn.Close()
localAddr := conn.LocalAddr().(*net.UDPAddr)
return localAddr.IP
}
cat << EOF > Dockerfile
FROM golang:alpine AS builder
ENV GO111MODULE=on \
CGO_ENABLED=0 \
GOOS=linux \
GOARCH=amd64
WORKDIR /build
COPY ./HTTPserver.go .
# Build the application
RUN go build -o HTTPserver ./HTTPserver.go
WORKDIR /dist
RUN cp /build/HTTPserver .
# Build a small image
FROM scratch
COPY --from=builder /dist/HTTPserver /
EXPOSE 8080
ENTRYPOINT ["/HTTPserver"]
EOF