有条件地在 Terraform 中创建单个模块

时间:2021-03-08 00:32:37

标签: terraform hcl terraform-modules

我一直在尝试有条件地使用根模块中的模块,以便在某些环境中不会创建该模块。许多人声称通过使用条件将模块中的 ''' This program lists lists the Google Compute Engine Instances in one zone ''' import time import json import jwt import requests import httplib2 # Project ID for this request. project = 'development-123456' # The name of the zone for this request. zone = 'us-west1-a' # Service Account Credentials, Json format json_filename = 'service-account.json' # Permissions to request for Access Token scopes = "https://www.googleapis.com/auth/cloud-platform" # Set how long this token will be valid in seconds expires_in = 3600 # Expires in 1 hour def load_json_credentials(filename): ''' Load the Google Service Account Credentials from Json file ''' with open(filename, 'r') as f: data = f.read() return json.loads(data) def load_private_key(json_cred): ''' Return the private key from the json credentials ''' return json_cred['private_key'] def create_signed_jwt(pkey, pkey_id, email, scope): ''' Create a Signed JWT from a service account Json credentials file This Signed JWT will later be exchanged for an Access Token ''' # Google Endpoint for creating OAuth 2.0 Access Tokens from Signed-JWT auth_url = "https://www.googleapis.com/oauth2/v4/token" issued = int(time.time()) expires = issued + expires_in # expires_in is in seconds # Note: this token expires and cannot be refreshed. The token must be recreated # JWT Headers additional_headers = { 'kid': pkey_id, "alg": "RS256", "typ": "JWT" # Google uses SHA256withRSA } # JWT Payload payload = { "iss": email, # Issuer claim "sub": email, # Issuer claim "aud": auth_url, # Audience claim "iat": issued, # Issued At claim "exp": expires, # Expire time "scope": scope # Permissions } # Encode the headers and payload and sign creating a Signed JWT (JWS) sig = jwt.encode(payload, pkey, algorithm="RS256", headers=additional_headers) return sig def exchangeJwtForAccessToken(signed_jwt): ''' This function takes a Signed JWT and exchanges it for a Google OAuth Access Token ''' auth_url = "https://www.googleapis.com/oauth2/v4/token" params = { "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": signed_jwt } r = requests.post(auth_url, data=params) if r.ok: return(r.json()['access_token'], '') return None, r.text def gce_list_instances(accessToken): ''' This functions lists the Google Compute Engine Instances in one zone ''' # Endpoint that we will call url = "https://www.googleapis.com/compute/v1/projects/" + project + "/zones/" + zone + "/instances" # One of the headers is "Authorization: Bearer $TOKEN" headers = { "Host": "www.googleapis.com", "Authorization": "Bearer " + accessToken, "Content-Type": "application/json" } h = httplib2.Http() resp, content = h.request(uri=url, method="GET", headers=headers) status = int(resp.status) if status < 200 or status >= 300: print('Error: HTTP Request failed') return j = json.loads(content.decode('utf-8').replace('\n', '')) print('Compute instances in zone', zone) print('------------------------------------------------------------') for item in j['items']: print(item['name']) if __name__ == '__main__': cred = load_json_credentials(json_filename) private_key = load_private_key(cred) s_jwt = create_signed_jwt( private_key, cred['private_key_id'], cred['client_email'], scopes) token, err = exchangeJwtForAccessToken(s_jwt) if token is None: print('Error:', err) exit(1) gce_list_instances(token) 设置为 0 或 1 可以解决问题。

count

然而,这改变了 module "conditionally_used_module" { source = "./modules/my_module" count = (var.create == true) ? 1 : 0 } 的类型:我们将拥有一个包含单个对象的列表(或元组),而不是一个对象(或映射)。有没有另一种方法可以实现这一点,这并不意味着改变模块的类型?

2 个答案:

答案 0 :(得分:0)

terraform-aws-eks 存储库显示了在“条件创建”块中实现您想要的示例。

答案 1 :(得分:0)

要有条件地创建一个模块,您可以使用一个变量,假设它在模块 create_modulevariables.tf 文件中被称为 conditionally_used_module

然后对于 conditionally_used_module 模块中的每个资源,您将使用 count 有条件地创建或不创建该特定资源。

以下示例应该可以工作并为您提供所需的效果。

# Set a variable to know if the resources inside the module should be created
module "conditionally_used_module" {
  source = "./modules/my_module"
  create_module = var.create
}

# Inside the conditionally_used_module file
# ( ./modules/my_module/main.tf ) most likely 
# for every resource inside use the count to create or not each resource
resource "resource_type" "resource_name" {
 count = var.create_module ? 1 : 0
 ... other resource properties 
}