<1> 프로비저닝 파이프라인 설계 - 깃허브 1 프로비저닝 파이프라인 + Github Action 준비 실습 실패~ 작업 순서는 확인하자. 2 실제 서비스가 실행되는 대상을 프로비저닝하면 테라폼의 Plan과 Apply 과정상에 추가로 코드 검증, 실행 계획 검증, 실행 후 결과 확인과 같은 추가 동작을 자동화. 도구 : 젠킨스, Github Action, TFC/TFE 3 저장소 포크 : https://github.com/terraform101/terraform-aws-github-action topasvga@naver.com 4 Github Action은 별도의 State 저장소를 제공하지 않기 때문에 테라폼 실행으로 생성되는 State가 항상 초기화되어 프로비저닝 결과를 유지할 수 없다. 백엔드를 활성화 하자. <2> 백엔드를 활성화 하자. 1 리모트 저장소를 로컬 환경에 복제 MyGit=<각자 자신의 깃허브 계정> MyGit=topasvga git clone https://github.com/$MyGit/terraform-aws-github-action # 확인 tree terraform-aws-github-action terraform-aws-github-action ├── files │ └── deploy_app.sh ├── LICENSE ├── main.tf ├── outputs.tf ├── README.md └── variables.tf cd terraform-aws-github-action git remote get-url origin 2 토큰 정보 확인 https://github.com/topasvga gb1! 설정 토큰 확인 오른쪽위 개인 아이콘 > Setting > 왼쪽 맨 아래 Developer settings > Personal access tokens Tockens(classic) > Generate new token 클릭 > 맨 아래 Generate new token (classic) test-seo1 repo체크 Generate token (Personal access tokens (classic) 을 복사해두자) 깃헙 액션 파이프라인 에러가 발생하시는 분은 레포지토리 Settings -> Actions -> General -> 최하단 Workflow permissions을 read and write permissions로 변경해보시고 재실행 해보세요. 3 push test? # echo "T101 Study" >> test.txt git add test.txt git commit -m "first commit" git push (정보를 넣어야 하는데 정보를 모른다) # 우선 Git 자격 증명 설정이 필요하다. git config --global user.name $MyGit git config --global user.email <깃허브 가입 이메일주소> git config --global user.email topasvga@naver.com cat ~/.gitconfig # push 실행을 위해서 로그인 정보 입력 git push Username for 'https://github.com': <깃허브 계정 정보> Password for 'https://topasvga@github.com': <토큰 정보> Username for 'https://github.com': topasvga Password for 'https://topasvga@github.com': <토큰 정보> 4 콘솔에서 확인 https://github.com/topasvga/terraform-aws-github-action 5 테라폼 클라우드를 사용할수 있도록 하자~ main.tf의 terraform 블록에서 사용자의 TFC 설정 organization으로 변경 확인 ? cat ~/.terraform.d/credentials.tfrc.json | jq 참고 테라폼 클라우드 토큰 받기 https://brunch.co.kr/@topasvga/3395 11. 5주 차 - 테라폼-협업 - 공유 저장소 사용 다음은 주말 CloudNet 테라폼 스터디 내용 참고하여 정리한 부분입니다. https://gasidaseo.notion.site/gasidaseo/CloudNet-Blog-c9dfa44a27ff431dafdd2edacc8a1863 <0> 명령서버 생성 <1> 형상 관리 도구 <2> 실습 - 로컬 작 brunch.co.kr/@topasvga/3395 3 main.tf 내용 수정 terraform { cloud { organization = "" # 생성한 ORG 이름 지정 topasvga-org hostname = "app.terraform.io" # default workspaces { name = "terraform-aws-github-action" } } ... 4 .github/workflow/action.yml 내용 수정 vi /root/terraform-aws-github-action/.github/workflows/action.yml env: MY_PREFIX: DEV TF_VERSION: 1.2.6 # 1.2.5에서 변경 // 테라폼이 로컬에서 실행되는건 아니고, 깃허브 액션에서 실행된다. 5 push git add main.tf git add .github/workflow/action.yml git commit -m "init" git push .github/workflow/action.yml 파일 push 시 에러 발생 시 → 깃허브 콘솔 > 세팅 > 해당 토큰에 workflow 권한 추가 후 다시 push 할 것 . 6 지정된 Terraform Cloud 백엔드 활성화를 위해 terraform init을 수행 cd /root/terraform-aws-github-action terraform init tree .terraform 7 생성된 TFC 간다. 워크스페이스 > 실행 모드 Execution mode를 Local로 수정 (저장소만 동기화해 사용함) > 저장 terraform-aws-github-action 워크스페이스(State 백엔드 역할만 수행) 확인 → 선택 후 좌측에 Settings 클릭 → General -> Local로 수정 > 저장 8 동작의 설명 ? github에서 풀리퀘스트 PR 하면 깃허브 액션이 돌아간다. SCAN - 테라폼 ---- Main 브랜치에서 PR 승인 ---- SCAN --테라폼- APPLY--- AWS 리소스 생성 (그림) 9 action.yml 파일 내용을 보라. jobs ? SCAN 실행됨. 검증하는 부분임. Terrafrom 테라폼. - Job Scan : 테라폼 코드 검증 - Check out code : 검증을 위해 저장소의 코드를 체크아웃 - Run terrascan : 테라폼 코드 검증 도구인 Terrascan을 실행 https://runterrascan.io/ https://runterrascan.io/docs/getting-started/ https://runterrascan.io/docs/integrations/cicd/ - Upload SARIF file : 검증의 결과(정적 분석 결과 표준 포맷)을 업로드 - Job ‘Terraform’ : 테라폼 실행 ← Job ‘Scan’ 이후 실행 - Check out code : 검증을 위해 저장소의 코드를 체크아웃 - Configure AWS credentials : AWS 환경을 프로비저닝하기 위한 Credential 설정 - Terraform Fmt : 표준 스타일 수정 대상 확인 - Terraform init : 테라폼 실행을 위한 init 수행 - Terraform validate : 코드 문법 오류 검사 - Terraform plan : 실행 계획 확인 - env.TF_LOG: info : 로그 수즌을 info로 출력해 실행 디버깅 - Plan output : 풀 리퀘스트인 경우 실행 계획을 정리해 출력 - Terraform apply : 메인 브랜치 변경 시에만 Apply 수행 - 예시의 동작 외에도 프로비저닝 이후의 테스트를 위한 terratest 도구와 비용 예측을 위한 terracost, infracost 도구들도 추가해볼 수 있다. - 코드 내용 설명 10 action.yml : Github Action의 구성은 .github/workflows의 yml 파일 형태로 작성 name: Terraform DEV on: push: branches: - main pull_request: env: MY_PREFIX: DEV TF_VERSION: 1.2.5 jobs: SCAN: name: SCAN runs-on: ubuntu-latest # env: # working-directory: terraform # TF_WORKSPACE: my-workspace steps: # - name: Configure AWS credentials # uses: aws-actions/configure-aws-credentials@v1 # with: # aws-region: eu-west-1 - name: Check out code uses: actions/checkout@v3 - name: Run Terrascan id: terrascan uses: tenable/terrascan-action@main with: iac_type: 'terraform' iac_version: 'v14' policy_type: 'aws' only_warn: true sarif_upload: true - name: Upload SARIF file uses: github/codeql-action/upload-sarif@v2 with: sarif_file: terrascan.sarif Terraform: needs: SCAN name: Terraform runs-on: ubuntu-latest steps: - name: Check out code uses: actions/checkout@v3 - uses: hashicorp/setup-terraform@v2 with: terraform_version: $TF_VERSION cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }} - name: Terraform Fmt id: fmt run: terraform fmt -recursive -check continue-on-error: true - name: Terraform init id: init run: terraform init -upgrade # working-directory: ${{ env.working-directory }} - name: Terraform validate id: validate run: terraform validate -no-color - name: Terraform plan id: plan run: terraform plan -no-color -var=prefix="$MY_PREFIX" # working-directory: ${{ env.working-directory }} env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} TF_LOG: info - name: Plan output id: output uses: actions/github-script@v3 if: github.event_name == 'pull_request' env: PLAN: "terraform\n${{ steps.plan.outputs.stdout }}" with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const output = `#### Terraform Format and Style �\`${{ steps.fmt.outcome }}\` #### Terraform Initialization ⚙️\`${{ steps.init.outcome }}\` #### Terraform Plan �\`${{ steps.plan.outcome }}\`
Show Plan \`\`\`hcl ${process.env.PLAN} \`\`\`
**Pusher**: @${{ github.actor }} **Action**: ${{ github.event_name }} `; github.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: output }) - name: Terraform apply id: apply if: github.ref == 'refs/heads/main' && github.event_name == 'push' run: terraform apply -auto-approve -var=prefix="$MY_PREFIX" -input=false env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 10. main.tf : 프로비저닝의 실행은 작업자나 Github Action에서 발생하더라도 동일한 State유지를 위해 백엔드 구성 추가 11 Github Action 과정에서 필요로 하는 State 공유를 위한 Terraform Cloud의 토큰, AWS 프로비저닝을 위한 AWS Credential과 같은 민감 데이터를 저장소에서 민감 변수로 처리할 수 있다. (옵션) AWS IAM 계정 생성 및 자격증명 획득 aws iam create-user --user-name testuser aws iam create-access-key --user-name testuser aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/AdministratorAccess --user-name testuser "AccessKeyId": "AKIWPLWXCWW", "SecretAccessKey": "1K/h1h231kGQBDs+PHhxF/M" 12 깃허브 액션 에서 해당 repository 저장소의 [Setting] → [Secrets and variables - Actions] 선택 ⇒ 3가지 새로운 민감 변수 등록 [New repository secret] Name : TF_API_TOKEN Secret : <각자 자신의 TFC Token> AWS_ACCESS_KEY_ID : AWS Access Key 입력 AWS_SECRET_ACCESS_KEY : AWS Secret Access Key 입력 13 깃허브 액션이 기본 비활성화이다. 본인 깃허브 계정것을 활성화 하자. 포크되어 비활성화되어 있는 저장소의 [Actions] 탭으로 이동해 [I understand my workflows, go ahead and enable them] 버튼을 클릭, 활성화한다 <3> 책 연습문제1, P259 - 브렌치 하나 따서 작업한다. 1 Automate Terraform with GitHub Actions 가이드 참고해서 토큰 생성 하고 실습 진행 2 브렌치 하나 따서 작업한다. - 브랜치 이름 : add-env-variable 테라폼 입력 변수 추가 - 이름 : environment - 설명 : Define infrastructure’s environment - 타입 : string - 기본값 : dev - 변수 확인 - 조건 : dev, qa, prod 인 경우 허용 - 에러 메시지 : The environment value must be dev, qa, or prod. - **aws_vpc**의 **tags.environment**를 입력 변수 **environment** 값으로 선언 - 새로운 브랜치의 변경 내용을 커밋, 푸시하고 깃허브 웹페이지에서 **풀 리퀘스트**를 생성한다 ← 주의: 자신의 저장소로 요청하는지 꼭 확인 - Github Action의 동작 조건은 메인 브랜치에 푸시가 발생하거나 풀 리퀘스트가 발생하는 경우로 정의되어 있다. 3 # Github Action의 실행 조건 : ./github/workflows/action.yml on: push: branches: - main pull_request: // main 프렌치에 push 되거나 pull_request 될때 , Github Action이 실행된다. 4 해결 ? 브랜치 생성 : add-env-variable cd /root/terraform-aws-github-action git branch git branch -M add-env-variable vi main.tf 내용 수정 resource "aws_vpc" "hashicat" { cidr_block = var.address_space enable_dns_hostnames = true tags = { name = "${var.prefix}-vpc-${var.region}" environment = var.environment # 원래 값 Production } } // variable "environment 정보 가져온다. 사용을 위해서는 아래 variable 만들어 줘야 한다!! 5 vi variables.tf 내용 추가 variable "environment" { type = string description = "Define infrastructure’s environment" default = "dev" validation { condition = contains(["dev", "qa", "prod"], var.environment) error_message = "The environment value must be dev, qa, or prod." } } 6 push terraform fmt git add . git commit -m "add env variable" git push origin HEAD 7 아래 링크로 간다~ remote: remote: Create a pull request for 'add-env-variable' on GitHub by visiting: remote: https://github.com/topasvga/terraform-aws-github-action/pull/new/add-env-variable remote: To https://github.com/topasvga/terraform-aws-github-action * [new branch] HEAD -> add-env-variable 8 반드시 본인의 저장소로 변경해야 한다. // 본인 레파지토리 저장소로 하자. 9 PR을 만들자. create pr Create pull request 7 Github에 Action 에 가서 확인하자 콘솔에서 action을 보자~~ scan 보자. 깃허브 action에 있는 sandbox 환경에서 돌아가고 있는것이다. Terraform plan에서 에러가 난다. # error 메시지 Terraform Unhandled error: HttpError: Resource not accessible by integration Terraform The following actions uses node12 which is deprecated and will be forced to run on node16: actions/github-script@v3. For more info: https://github.blog/changelog/2023-06-13-github-actions-all-actions-will-run-on-node16-instead-of-node12-by-default/ 9 동작 성공 시 → Main RP 병합 수행 ⇒ Github Action 에서 Apply 수행 - AWS 서울 리전에 리소스 생성 확인 - Github Action 확인 - Github Security 에 정적 코드 분석 내용 확인 : [runterrascan.io](http://runterrascan.io) 동작 실패로 관련 리소스 삭제 1. Github Repo 삭제 ? 레파지토리 https://github.com/topasvga/terraform-aws-github-action > 세팅 > 맨아래 > 삭제 2. TFC Workspace 삭제 ? workspace > 해당 워크스페이스 terraform-aws-github-action > Destruction and Deletion > terraform-aws-github-action 3. 로컬에 코드 폴더 삭제 rm -rf terraform-aws-collaboration rm -rf terraform-aws-github-action