如何使用 Go、Terraform 和 AWS 构建简历 API

2025-05-24

如何使用 Go、Terraform 和 AWS 构建简历 API

背景

受到Sara Vieira的启发,我开始在互联网上构建更多“傻瓜”的东西,以此来补充我的灵魂,并在实践中学习。今年我想学习 Go ,在学习了Stephen Grider 的Go:Go 开发者完整指南(Golang)》之后,我想构建一些简单的东西来继续我的 Go 之旅。我决定为我的基于 JSON 的标准格式简历构建一个开源 REST API 。我的应用程序使用Go ,基础设施即代码 (IaC)使用Terraform ,并使用Terraform Cloud来配置我的基础设施,无论是按需配置还是响应各种事件。我正在使用Circle CI /CD 管道将应用程序部署到AWS Lambda 。

所有代码都可以在我的 GitHub上找到。

演示

你可以通过 curl REST API 查看我的简历

curl -L https://resume.mattjarrett.dev
Enter fullscreen mode Exit fullscreen mode

设置

如果您想部署代码,则需要在本地设置 Go 和 Terraform,并在Terraform CloudAWS上拥有一个帐户。

使用 JSON 创建简历

我复制了基于 JSON 格式的标准简历架构,并将其添加到我的信息中。编辑完 JSON 后,我得到了这个。

{
  "basics": {
    "name": "Matt Jarrett",
    "label": "Full Stack Developer",
    "picture": "https://mattjarrett.dev/img/header.jpg",
    "email": "",
    "phone": "",
    "website": "https://mattjarrett.dev/",
    "summary": "Dad. Husband. Full Stack Developer. JavaScript Enthusiast. Aspiring Designer. Cyclist. I'm a passionate and detail oriented full stack software developer based in Dallas, Texas. Experienced leader where I enjoy design, clean code, and building positive team environments and strong developer experiences. I enjoy turning problems into solutions that make people smile. I enjoy continuous learning and exploring new technologies. When I'm not coding at home or work, I enjoy time with my family and photography.",
    "location": {
      "address": "",
      "postalCode": "",
      "city": "Dallas",
      "countryCode": "US",
      "region": "Texas"
    },
    "profiles": [
      {
        "network": "Linkedin",
        "username": "Matt Jarrett",
        "url": "https://www.linkedin.com/in/matt-jarrett-303a75144/"
      },
      {
        "network": "GitHub",
        "username": "cujarrett",
        "url": "https://github.com/cujarrett"
      },
      {
        "network": "Twitter",
        "username": "cujarrett",
        "url": "https://twitter.com/home"
      }
    ]
  },
  "work": [
    {
      "company": "State Farm",
      "position": "Technology Engineer",
      "website": "https://www.statefarm.com",
      "startDate": "2011-11-01",
      "endDate": "N/A",
      "summary": "State Farm is the largest property and casualty insurance provider in the United States. It is also the largest auto insurance provider in the United States. State Farm is ranked 36th in the 2019 Fortune 500, which lists American companies by revenue.",
      "highlights": [
        "Advancing Cloud Native and DevOps transformations in the telematics platform space. Working with an exciting mix of technology including public cloud, mobile, and legacy systems. Working daily on not only technology but also culture.",
        "Built new solutions using React, Node, NOSQL, REST, Kubernetes, GitLab, CI/CD, Grafana, and Prometheus for enablement of large high priority enterprise initiatives. Mentored several team members in modern technology. Designed solutions for implementation. Taught classes on modern JavaScript.",
        "Designed and implemented many successful web services allowing developers on demand access to safe fabricated data for a variety of needs and automation. It's since been used millions of times across the enterprise, enabling development teams to focus on improving customer experience.",
        "Designed and implemented an automated infrastructure solution offering a complete stand up and tear down process accomplished in minutes compared to days.",
        "Taught Java in Enterprise Java classes to spread knowledge. Active member of the college recruitment team including creation of campus events, hacks, and interviews. Mentored many college interns through a successful internships resulting in all receiving and accepting full time positions. Designed and implemented multiple solutions in Java."
      ]
    }
  ],
  "volunteer": [
    {
      "organization": "Tech Titans",
      "position": "Speaker",
      "website": "https://techtitans.org/",
      "startDate": "2017-01-01",
      "endDate": "N/A",
      "summary": "Tech Titans is a forum that leverages the regional technology community to collaborate, share and inspire creative thinking that fuels tomorrow’s innovations.",
      "highlights": [
        "I Spoke at many events over the years with audiences including teachers and students."
      ]
    }
  ],
  "education": [
    {
      "institution": "Illinois State University",
      "area": "Information Technology",
      "studyType": "Bachelor",
      "startDate": "2009-06-01",
      "endDate": "2011-01-01",
      "gpa": "3.87/4.0",
      "courses": []
    }
  ],
  "awards": [],
  "publications": [],
  "skills": [
    {
      "name": "AWS",
      "level": "Intermediate",
      "keywords": [
        "Cloud",
        "Lambda",
        "S3",
        "CloudFront"
      ]
    },
    {
      "name": "JavaScript",
      "level": "Expert",
      "keywords": [
        "ECMAScript",
        "ES6",
        "Node.js",
        "Web",
        "Front End"
      ]
    },
    {
      "name": "React",
      "level": "Pro",
      "keywords": [
        "SPA",
        "Web",
        "Front End"
      ]
    },
    {
      "name": "Vue",
      "level": "Intermediate",
      "keywords": [
        "SPA",
        "Web",
        "Front End"
      ]
    },
    {
      "name": "Angular",
      "level": "Intermediate",
      "keywords": [
        "SPA",
        "Web",
        "Front End"
      ]
    },
    {
      "name": "Go",
      "level": "Intermediate",
      "keywords": [
        "Golang"
      ]
    },
    {
      "name": "Kubernetes",
      "level": "Pro",
      "keywords": [
        "K8s",
        "CKAD"
      ]
    },
    {
      "name": "Docker",
      "level": "Intermediate",
      "keywords": [
        "Containers"
      ]
    },
    {
      "name": "Design",
      "level": "Intermediate",
      "keywords": [
        "Web",
        "Front End"
      ]
    },
    {
      "name": "Linux",
      "level": "Intermediate",
      "keywords": [
        "Bash",
        "Shell"
      ]
    },
    {
      "name": "NOSQL",
      "level": "Pro",
      "keywords": [
        "Couch",
        "Dynamo"
      ]
    },
    {
      "name": "SQL",
      "level": "Pro",
      "keywords": [
        "PostgreSQL",
        "Aurora"
      ]
    },
    {
      "name": "GitHub",
      "level": "Expert",
      "keywords": [
        "SDLC",
        "OSS",
        "CI/CD"
      ]
    },
    {
      "name": "GitLab",
      "level": "Expert",
      "keywords": [
        "SDLC",
        "OSS",
        "CI/CD"
      ]
    },
    {
      "name": "Pipelines",
      "level": "Expert",
      "keywords": [
        "DevOps"
      ]
    },
    {
      "name": "Grafana",
      "level": "Expert",
      "keywords": [
        "DevOps",
        "Observability",
        "Dashboards",
        "SRE",
        "SLO"
      ]
    },
    {
      "name": "Prometheus",
      "level": "Expert",
      "keywords": [
        "DevOps",
        "Observability",
        "Dashboards",
        "SRE",
        "SLO"
      ]
    },
    {
      "name": "Java",
      "level": "Pro",
      "keywords": []
    },
    {
      "name": "Photoshop",
      "level": "Expert",
      "keywords": []
    },
    {
      "name": "Python",
      "level": "Intermediate",
      "keywords": []
    }
  ],
  "languages": [
    {
      "language": "English",
      "fluency": "Native speaker"
    }
  ],
  "interests": [
    {
      "name": "Cycling",
      "keywords": [
        "MTB",
        "Gravel",
        "Road"
      ]
    },
    {
      "name": "Photography",
      "keywords": [
        "Weddings",
        "Landscape",
        "Senior"
      ]
    }
  ],
  "references": [
    {
      "name": "Caleb Lemoine",
      "reference": "Matt is one of the best engineers I've had the pleasure of working with and knowing personally. He would be a highly valued asset anywhere."
    },
    {
      "name": "Lucas Reardon",
      "reference": "Matt Jarrett's passion for technology is infectious. His brand as a forward-thinking leader and influencer raises the performance of those around him as well as the products and capabilities he touches. If you're building a team, you want Matt. Full stop."
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

创建结构体

完成编辑后,我使用Matt Holt创建的这个 rad JSON 到 Go struct 应用程序将我的 JSON 转换为 Go 的 JSON 等效项struct

在我struct为每个部分做出之后。

type Resume struct {
    Basics       Basics      `json:"basics"`
    Work         []Work      `json:"work"`
    Volunteer    []Volunteer `json:"volunteer"`
    Education    []Education `json:"education"`
    Awards       []string    `json:"awards"`
    Publications []string    `json:"publications"`
    Skills       []Skill     `json:"skills"`
    Languages    []Language  `json:"languages"`
    Interests    []Interest  `json:"interests"`
    References   []Reference `json:"references"`
}

type Basics struct {
    Name     string    `json:"name"`
    Label    string    `json:"label"`
    Picture  string    `json:"picture"`
    Email    string    `json:"email"`
    Phone    string    `json:"phone"`
    Website  string    `json:"website"`
    Summary  string    `json:"summary"`
    Location Location  `json:"location"`
    Profiles []Profile `json:"profiles"`
}

type Location struct {
    Address     string `json:"address"`
    PostalCode  string `json:"postalCode"`
    City        string `json:"city"`
    CountryCode string `json:"countryCode"`
    Region      string `json:"region"`
}

type Profile struct {
    Network  string `json:"network"`
    Username string `json:"username"`
    URL      string `json:"url"`
}

type Work struct {
    Company    string   `json:"company"`
    Position   string   `json:"position"`
    Website    string   `json:"website"`
    StartDate  string   `json:"startDate"`
    EndDate    string   `json:"endDate"`
    Summary    string   `json:"summary"`
    Highlights []string `json:"highlights"`
}

type Volunteer struct {
    Organization string   `json:"organization"`
    Position     string   `json:"position"`
    Website      string   `json:"website"`
    StartDate    string   `json:"startDate"`
    EndDate      string   `json:"endDate"`
    Summary      string   `json:"summary"`
    Highlights   []string `json:"highlights"`
}

type Education struct {
    Institution string   `json:"institution"`
    Area        string   `json:"area"`
    StudyType   string   `json:"studyType"`
    StartDate   string   `json:"startDate"`
    EndDate     string   `json:"endDate"`
    Gpa         string   `json:"gpa"`
    Courses     []string `json:"courses"`
}

type Skill struct {
    Name     string   `json:"name"`
    Level    string   `json:"level"`
    Keywords []string `json:"keywords"`
}

type Language struct {
    Language string `json:"language"`
    Fluency  string `json:"fluency"`
}

type Interest struct {
    Name     string   `json:"name"`
    Keywords []string `json:"keywords"`
}

type Reference struct {
    Name      string `json:"name"`
    Reference string `json:"reference"`
}
Enter fullscreen mode Exit fullscreen mode

接下来我制作了一个func填充结构

func getResume() *Resume {
    return &Resume{
        Basics: Basics{
            Name:    "Matt Jarrett",
            Label:   "Full Stack Developer",
            Picture: "https://mattjarrett.dev/img/header.jpg",
            Email:   "",
            Phone:   "",
            Website: "https://mattjarrett.dev/",
            Summary: "Dad. Husband. Full Stack Developer. JavaScript Enthusiast. Aspiring Designer. Cyclist. I'm a passionate and detail oriented full stack software developer based in Dallas, Texas. Experienced leader where I enjoy design, clean code, and building positive team environments and strong developer experiences. I enjoy turning problems into solutions that make people smile. I enjoy continuous learning and exploring new technologies. When I'm not coding at home or work, I enjoy time with my family and photography.",
            Location: Location{
                Address:     "",
                PostalCode:  "",
                City:        "Dallas",
                CountryCode: "US",
                Region:      "Texas",
            },
            Profiles: []Profile{
                {
                    Network:  "Linkedin",
                    Username: "Matt Jarrett",
                    URL:      "https://www.linkedin.com/in/matt-jarrett-303a75144/",
                }, {
                    Network:  "GitHub",
                    Username: "cujarrett",
                    URL:      "https://github.com/cujarrett",
                }, {
                    Network:  "Twitter",
                    Username: "cujarrett",
                    URL:      "https://twitter.com/home",
                },
            },
        },
        Work: []Work{
            {
                Company:   "State Farm",
                Position:  "Technology Engineer",
                Website:   "https://www.statefarm.com",
                StartDate: "2011-11-01",
                EndDate:   "N/A",
                Summary:   "State Farm is the largest property and casualty insurance provider in the United States. It is also the largest auto insurance provider in the United States. State Farm is ranked 36th in the 2019 Fortune 500, which lists American companies by revenue.",
                Highlights: []string{
                    "Advancing Cloud Native and DevOps transformations in the telematics platform space. Working with an exciting mix of technology including public cloud, mobile, and legacy systems. Working daily on not only technology but also culture.",
                    "Built new solutions using React, Node, NOSQL, REST, Kubernetes, GitLab, CI/CD, Grafana, and Prometheus for enablement of large high priority enterprise initiatives. Mentored several team members in modern technology. Designed solutions for implementation. Taught classes on modern JavaScript.",
                    "Designed and implemented many successful web services allowing developers on demand access to safe fabricated data for a variety of needs and automation. It's since been used millions of times across the enterprise, enabling development teams to focus on improving customer experience.",
                    "Designed and implemented an automated infrastructure solution offering a complete stand up and tear down process accomplished in minutes compared to days.",
                    "Taught Java in Enterprise Java classes to spread knowledge. Active member of the college recruitment team including creation of campus events, hacks, and interviews. Mentored many college interns through a successful internships resulting in all receiving and accepting full time positions. Designed and implemented multiple solutions in Java."},
            },
        },
        Volunteer: []Volunteer{
            {
                Organization: "Tech Titans",
                Position:     "Speaker",
                Website:      "https://techtitans.org/",
                StartDate:    "2017-01-01",
                EndDate:      "N/A",
                Summary:      "Tech Titans is a forum that leverages the regional technology community to collaborate, share and inspire creative thinking that fuels tomorrow’s innovations.",
                Highlights:   []string{"I Spoke at many events over the years with audiences including teachers and students."},
            },
        },
        Education: []Education{
            {
                Institution: "Illinois State University",
                Area:        "Information Technology",
                StudyType:   "Bachelor",
                StartDate:   "2009-06-01",
                EndDate:     "2011-01-01",
                Gpa:         "3.87/4.0",
                Courses:     []string{},
            },
        },
        Awards:       []string{},
        Publications: []string{},
        Skills: []Skill{
            {
                Name:  "AWS",
                Level: "Intermediate",
                Keywords: []string{
                    "Cloud", "Lambda", "S3", "CloudFront",
                },
            }, {
                Name:  "JavaScript",
                Level: "Expert",
                Keywords: []string{
                    "ECMAScript", "ES6", "Node.js", "Web", "Front End",
                },
            }, {
                Name:  "React",
                Level: "Pro",
                Keywords: []string{
                    "SPA", "Web", "Front End",
                },
            }, {
                Name:  "Vue",
                Level: "Intermediate",
                Keywords: []string{
                    "SPA", "Web", "Front End",
                },
            }, {
                Name:  "Angular",
                Level: "Intermediate",
                Keywords: []string{
                    "SPA", "Web", "Front End",
                },
            }, {
                Name:  "Go",
                Level: "Intermediate",
                Keywords: []string{
                    "Golang",
                },
            }, {
                Name:  "Kubernetes",
                Level: "Pro",
                Keywords: []string{
                    "K8s", "CKAD",
                },
            }, {
                Name:  "Docker",
                Level: "Intermediate",
                Keywords: []string{
                    "Containers",
                },
            }, {
                Name:  "Design",
                Level: "Intermediate",
                Keywords: []string{
                    "Web", "Front End",
                },
            }, {
                Name:  "Linux",
                Level: "Intermediate",
                Keywords: []string{
                    "Bash", "Shell",
                },
            }, {
                Name:  "NOSQL",
                Level: "Pro",
                Keywords: []string{
                    "Couch", "Dynamo",
                },
            }, {
                Name:  "SQL",
                Level: "Pro",
                Keywords: []string{
                    "PostgreSQL", "Aurora",
                },
            }, {
                Name:  "GitHub",
                Level: "Expert",
                Keywords: []string{
                    "SDLC", "OSS", "CI/CD",
                },
            }, {
                Name:  "GitLab",
                Level: "Expert",
                Keywords: []string{
                    "SDLC", "OSS", "CI/CD",
                },
            }, {
                Name:  "Pipelines",
                Level: "Expert",
                Keywords: []string{
                    "DevOps",
                },
            }, {
                Name:  "Grafana",
                Level: "Expert",
                Keywords: []string{
                    "DevOps", "Observability", "Dashboards", "SRE", "SLO",
                },
            }, {
                Name:  "Prometheus",
                Level: "Expert",
                Keywords: []string{
                    "DevOps", "Observability", "Dashboards", "SRE", "SLO",
                },
            }, {
                Name:     "Java",
                Level:    "Pro",
                Keywords: []string{},
            }, {
                Name:     "Photoshop",
                Level:    "Expert",
                Keywords: []string{},
            }, {
                Name:     "Python",
                Level:    "Intermediate",
                Keywords: []string{},
            },
        },
        Languages: []Language{
            {
                Language: "English",
                Fluency:  "Native speaker",
            },
        },
        Interests: []Interest{
            {
                Name: "Cycling",
                Keywords: []string{
                    "MTB", "Gravel", "Road",
                },
            }, {
                Name: "Photography",
                Keywords: []string{
                    "Weddings", "Landscape", "Senior",
                },
            },
        },
        References: []Reference{
            {
                Name:      "Caleb Lemoine",
                Reference: "Matt is one of the best engineers I've had the pleasure of working with and knowing personally. He would be a highly valued asset anywhere.",
            },
            {
                Name:      "Lucas Reardon",
                Reference: "Matt Jarrett's passion for technology is infectious. His brand as a forward-thinking leader and influencer raises the performance of those around him as well as the products and capabilities he touches. If you're building a team, you want Matt. Full stop.",
            },
        },
    }
}
Enter fullscreen mode Exit fullscreen mode

格式化响应 JSON

为了便于阅读,我想返回一个格式化的 JSON。我写了这个func来实现。

func (input Resume) formatResume() string {
    bytesBuffer := new(bytes.Buffer)
    json.NewEncoder(bytesBuffer).Encode(&input)

    responseBytes := bytesBuffer.Bytes()

    var prettyJSON bytes.Buffer
    error := json.Indent(&prettyJSON, responseBytes, "", "  ")
    if error != nil {
        log.Println("JSON parse error: ", error)
    }
    formattedResume := string(prettyJSON.Bytes())
    return formattedResume
}
Enter fullscreen mode Exit fullscreen mode

提供 API

我使用 AWS 的 API 网关通过 Lambda 处理请求func

func handleRequest(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
    resume := getResume()
    formattedResume := resume.formatResume()

    response := events.APIGatewayProxyResponse{
        StatusCode: http.StatusOK,
        Headers:    map[string]string{"Content-Type": "application/json"},
        Body:       formattedResume,
    }
    return response, nil
}
Enter fullscreen mode Exit fullscreen mode

主要的

我通过调用来设置我的主要处理请求handleRequest

func main() {
    lambda.Start(handleRequest)
}
Enter fullscreen mode Exit fullscreen mode

使用 Terraform 配置基础设施

我使用Terraform作为我的基础设施即代码 (IaC)。我使用AWS Lambda进行计算,并通过AWS API Gateway提供该计算服务。

在我探索云和 Terraform 的过程中,我有时会发现配置基础设施和应用程序之间的界限变得模糊。我倾向于将配置基础设施(无论是按需配置还是响应各种事件)与用于运行持续集成和持续部署的 CI/CD 管道区分开来。为了实现这一点resume-api,我不得不绕过 AWS Lambda,使其在创建时获取计算代码。我选择在基础设施配置时使用占位符来处理这个问题,然后使用Circle CI /CD 管道构建 Lambda,并在 GitHub 的拉取请求发生更改时使用实际代码更新 Lambda。

我正在使用Terraform Cloud来配置我的基础设施,既可以按需配置,也可以响应各种事件。设置好 Terraform Cloud 项目工作区后,我更新了工作区,将所有应用都改为手动完成,这样每次变更我仍然可以收到自动更新计划,但只有手动点击Terraform Cloudresume-api时,基础设施才会更新。apply

将 Terraform Cloud 设置为手动应用

这就是 Terraform Cloud 运行的样子。
Terraform 云

variable "aws_region" {
  description = "AWS region for the infrastructure"
  type = string
  default = "us-east-1"
}

data "archive_file" "placeholder" {
  type = "zip"
  output_path = "${path.module}/lambda-function-payload.zip"

  source {
    content = "placeholder"
    filename = "placeholder.txt"
  }
}

provider "aws" {
  region = var.aws_region
}

# Define a Lambda function.
#
# The handler is the name of the executable for go1.x runtime.
resource "aws_lambda_function" "resume-api" {
  filename = data.archive_file.placeholder.output_path
  function_name = "resume-api"
  handler       = "resume-api"
  role          = aws_iam_role.resume-api.arn
  runtime       = "go1.x"
  memory_size   = 128
  timeout       = 1
}

# A Lambda function may access to other AWS resources such as S3 bucket. So an
# IAM role needs to be defined. This example does not access to any resource,
# so the role is empty.
#
# The date 2012-10-17 is just the version of the policy language used here [1].
#
# [1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_version.html
resource "aws_iam_role" "resume-api" {
  name               = "resume-api"
  assume_role_policy = <<POLICY
{
  "Version": "2012-10-17",
  "Statement": {
    "Action": "sts:AssumeRole",
    "Principal": {
      "Service": "lambda.amazonaws.com"
    },
    "Effect": "Allow"
  }
}
POLICY
}

# Allow API gateway to invoke the resume-api Lambda function.
resource "aws_lambda_permission" "resume-api" {
  statement_id  = "AllowAPIGatewayInvoke"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.resume-api.arn
  principal     = "apigateway.amazonaws.com"
}

# A Lambda function is not a usual public REST API. We need to use AWS API
# Gateway to map a Lambda function to an HTTP endpoint.
resource "aws_api_gateway_resource" "resume-api" {
  rest_api_id = aws_api_gateway_rest_api.resume-api.id
  parent_id   = aws_api_gateway_rest_api.resume-api.root_resource_id
  path_part   = "resume-api"
}

resource "aws_api_gateway_rest_api" "resume-api" {
  name = "resume-api"
}

#           GET
# Internet -----> API Gateway
resource "aws_api_gateway_method" "resume-api" {
  rest_api_id   = aws_api_gateway_rest_api.resume-api.id
  resource_id   = aws_api_gateway_resource.resume-api.id
  http_method   = "GET"
  authorization = "NONE"
}

#              POST
# API Gateway ------> Lambda
# For Lambda the method is always POST and the type is always AWS_PROXY.
#
# The date 2015-03-31 in the URI is just the version of AWS Lambda.
resource "aws_api_gateway_integration" "resume-api" {
  rest_api_id             = aws_api_gateway_rest_api.resume-api.id
  resource_id             = aws_api_gateway_resource.resume-api.id
  http_method             = aws_api_gateway_method.resume-api.http_method
  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = "arn:aws:apigateway:${var.aws_region}:lambda:path/2015-03-31/functions/${aws_lambda_function.resume-api.arn}/invocations"
}

# This resource defines the URL of the API Gateway.
resource "aws_api_gateway_deployment" "resume-api_v1" {
  depends_on = [
    aws_api_gateway_integration.resume-api
  ]
  rest_api_id = aws_api_gateway_rest_api.resume-api.id
  stage_name  = "v1"
}

# Set the generated URL as an output. Run `terraform output url` to get this.
output "url" {
  value = "${aws_api_gateway_deployment.resume-api_v1.invoke_url}${aws_api_gateway_resource.resume-api.path}"
}
Enter fullscreen mode Exit fullscreen mode

Makefile

我制作了一个Makefile用于运行项目相关任务的。

clean:
    go clean

install:
    go get -v -t -d ./...

test:
    go test -v ./...

compile:
    GOOS=linux go build -o resume-api main.go
Enter fullscreen mode Exit fullscreen mode

使用 Circle CI 进行 CI/CD

在我配置好基础设施并经过自动化质量测试后,我就可以自由地使用 Circle CI/CD 管道更新 Lambda 代码。

# Golang CircleCI 2.0 configuration file
# Check https://circleci.com/docs/2.0/language-go/ for more details
version: 2
jobs:

  test:
    docker:
      - image: circleci/golang:1.14
    working_directory: /go/src/github.com/cujarrett/resume-api
    steps:
      - checkout
      - run:
          name: Install dependencies
          command: make install
      - run:
          name: Run tests
          command:  make test

  build:
    docker:
      - image: circleci/golang:1.14
    working_directory: ~/temp
    steps:
      - checkout
      - run:
          name: Install dependencies
          command: make install
      - run:
          name: Build executable
          command: make compile
      - run:
          name: Make temp build folder
          command: mkdir build
      - run:
          name: Zip executable
          command: zip build/resume-api.zip -q resume-api
      - persist_to_workspace:
          root: .
          paths:
            - build/resume-api.zip

  deploy:
    docker:
      - image: 'circleci/python:3.7.6'
    working_directory: ~/temp
    steps:
      - attach_workspace:
          at: ~/temp
      - run:
          name: Install AWS CLI
          command: sudo pip install awscli
      - deploy:
          name: Deploy to AWS S3
          command: |
            aws lambda update-function-code \
              --function-name=resume-api \
              --zip-file=fileb://build/resume-api.zip 1> /dev/null \
              --region=us-east-1

workflows:
  version: 2
  cicd:
    jobs:
      - test
      - build:
          requires:
            - test
      - deploy:
          requires:
            - build
          filters:
            branches:
              only: master
Enter fullscreen mode Exit fullscreen mode

现在,每个分支的拉取请求都会触发terraform plan所有质量测试,并在合并时将应用程序部署到 AWS。

结论

我玩得很开心。我学到了比以前更多一些的 Go、Terraform 和 Terraform Cloud。如果我犯了什么错误,我很乐意吸取教训。

链接

文章来源:https://dev.to/cujarrett/how-i-built-a-resume-api-w-go-terraform-and-aws-371o
PREV
Web 应用程序无聊堆栈 wemake-python-styleguide
NEXT
Cube.js,开源仪表板框架:终极指南