-
Terraform Cloud 활용하기Terraform 2023. 8. 12. 11:47
Terraform Cloud
Terraform cloud란 이름 그대로 Terraform 의 운영환경을 cloud 를 통해 관리할 수 있도록 해주는 서비스다.
장점
- State파일 관리를 위해 별도의 리소스를 생성할 필요가 없다.
- 사용자별로 허용 권한을 관리 할 수 있다.
- Sentinel을 사용해 생성할 리소스를 제한 할 수 있다.
- VCS 연동을 통해 자동화가 가능하다.단점
- Agent의 수가 정해져 있기 때문에 실행 속도가 느리다.
- TFC가 Cloud리소스 생성시 권한이 필요하다.
- TFC의 Token을 관리해야 되기 때문에 관리 포인트가 늘 수 있다.
- free tier은 기능제한이 있기 때문에 추가 기능을 위해 라이센스 구매시 비용이 증가한다.
TFC Dynamic Credentials
정적 자격 증명 사용시 Credentials를 TFC에 등록해야 하는데 이 또한 관리 포인트가 늘어나게 되며, 보안을 위해 Credentials를 주기적으로 교체하는게 좋다. 이를 위해 정적 자격 증명이 아닌 동적 자격 증명을 사용 할 수 있다.
동작 방식
TFC Variables
TFC에 Dynamoci Credentials를 사용하기 위한 Variables를 등록해야 한다.
Required Environment Variables
Variable Value Description TFC_AWS_PROVIDER_AUTH true true로 설정하지 않으면 Terraform Cloud가 AWS 인증을 수행하지 않습니다. TFC_AWS_RUN_ROLE_ARN aws role ARN TFC_AWS_PLAN_ROLE_ARN 및 TFC_AWS_APPLY_ROLE_ARN이 모두 선언되었을땐 생략할 수 있습니다. Optional Environment Variables
Variable Value Description TFC_AWS_WORKLOAD_IDENTITY_AUDIENCE 기본값은aws.workload.identity입니다. TFC_AWS_PLAN_ROLE_ARN Plan을 실행하는 역할의 ARN 값을 입력하지 않으면 TFC_AWS_RUN_ROLE_ARN으로 대체됩니다. TFC_AWS_APPLY_ROLE_ARN Apply를 실행하는 역할의 ARN 값을 입력하지 않으면 TFC_AWS_RUN_ROLE_ARN으로 대체됩니다. 구성
AWS.tf
# Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 provider "aws" { region = "ap-northeast-2" profile = var.profile } # Data source used to grab the TLS certificate for Terraform Cloud. # # https://registry.terraform.io/providers/hashicorp/tls/latest/docs/data-sources/certificate data "tls_certificate" "tfc_certificate" { url = "https://${var.tfc_hostname}" } # Creates an OIDC provider which is restricted to # # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_openid_connect_provider resource "aws_iam_openid_connect_provider" "tfc_provider" { url = data.tls_certificate.tfc_certificate.url client_id_list = [var.tfc_aws_audience] thumbprint_list = [data.tls_certificate.tfc_certificate.certificates[0].sha1_fingerprint] } # Creates a role which can only be used by the specified Terraform # cloud workspace. # # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role resource "aws_iam_role" "tfc_role" { name = "tfc-role" assume_role_policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "${aws_iam_openid_connect_provider.tfc_provider.arn}" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "${var.tfc_hostname}:aud": "${one(aws_iam_openid_connect_provider.tfc_provider.client_id_list)}" }, "StringLike": { "${var.tfc_hostname}:sub": "organization:${var.tfc_organization_name}:project:${var.tfc_project_name}:workspace:${var.tfc_workspace_name}:run_phase:*" } } } ] } EOF } # Creates a policy that will be used to define the permissions that # the previously created role has within AWS. # # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy resource "aws_iam_policy" "tfc_policy" { name = "tfc-policy" description = "TFC run policy" policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": "*" } ] } EOF } # Creates an attachment to associate the above policy with the # previously created role. # # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment resource "aws_iam_role_policy_attachment" "tfc_policy_attachment" { role = aws_iam_role.tfc_role.name policy_arn = aws_iam_policy.tfc_policy.arn } data "aws_iam_policy" "admin_policy" { name = "AdministratorAccess" } resource "aws_iam_role_policy_attachment" "admin_policy_attachment" { role = aws_iam_role.tfc_role.name policy_arn = data.aws_iam_policy.admin_policy.arn }
- aws_iam_openid_connect_provider : OIDC 생성 블록
- aws_iam_role : terraform cloud가 사용할 역할 생성
- aws_iam_policy : terraform cloud role에 연결할 정책 생성
- aws_iam_role_policy_attachment : role에 정책 연결
TFC.tf
# Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 provider "tfe" { hostname = var.tfc_hostname } # Runs in this workspace will be automatically authenticated # to AWS with the permissions set in the AWS policy. # # https://registry.terraform.io/providers/hashicorp/tfe/latest/docs/resources/workspace data "tfe_project" "this" { name = var.tfc_project_name organization = var.tfc_organization_name } # data "tfe_oauth_client" "gitlab" { # organization = var.tfc_organization # name = var.client_name # } resource "tfe_workspace" "my_workspace" { name = var.tfc_workspace_name organization = var.tfc_organization_name project_id = data.tfe_project.this.id tag_names = var.tfc_workspace_tags auto_apply = true execution_mode = "remote" # excution_mode is local or remote } # The following variables must be set to allow runs # to authenticate to AWS. # # https://registry.terraform.io/providers/hashicorp/tfe/latest/docs/resources/variable resource "tfe_variable" "enable_aws_provider_auth" { workspace_id = tfe_workspace.my_workspace.id key = "TFC_AWS_PROVIDER_AUTH" value = "true" category = "env" description = "Enable the Workload Identity integration for AWS." } resource "tfe_variable" "tfc_aws_role_arn" { workspace_id = tfe_workspace.my_workspace.id key = "TFC_AWS_RUN_ROLE_ARN" value = aws_iam_role.tfc_role.arn category = "env" description = "The AWS role arn runs will use to authenticate." } # The following variables are optional; uncomment the ones you need! # resource "tfe_variable" "tfc_aws_audience" { # workspace_id = tfe_workspace.my_workspace.id # key = "TFC_AWS_WORKLOAD_IDENTITY_AUDIENCE" # value = var.tfc_aws_audience # category = "env" # description = "The value to use as the audience claim in run identity tokens" # }
- tfe_workspace : terraform cloud workspace 생성
- auto_apply : terraform plan이 성공할때 자동으로 apply를 실행할 지 여부로 기본값은 false입니다.
- excution_mode : terraforl 실행 위치로 remote, local로 설정이 가능하며 기본값은 remote입니다.
variables.tf
# Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 variable "profile" { type = string default = "default" description = "aws config profile" } variable "tfc_aws_audience" { type = string default = "aws.workload.identity" description = "The audience value to use in run identity tokens" } variable "tfc_hostname" { type = string default = "app.terraform.io" description = "The hostname of the TFC or TFE instance you'd like to use with AWS" } variable "tfc_organization_name" { type = string description = "The name of your Terraform Cloud organization" } variable "tfc_project_name" { type = string default = "Default Project" description = "The project under which a workspace will be created" } variable "tfc_workspace_name" { type = string default = "my-aws-workspace" description = "The name of the workspace that you'd like to create and connect to AWS" } variable "tfc_workspace_tags" { type = list(any) default = ["ctc-csa-team4", "burning"] }
Reference
https://github.com/hashicorp/terraform-dynamic-credentials-setup-examples/tree/main/aws
'Terraform' 카테고리의 다른 글
Terraform Cloud 활용하기 #2 (0) 2023.08.20 Terraform Study 4주차 (0) 2023.07.29 Terraform Study 3주차 (0) 2023.07.22 Terraform Study 2주차 도전 과제 (0) 2023.07.15