Skip to content

Commit f40d595

Browse files
authored
Merge pull request #5 from nrkno/wait-for-azure
2 parents 1d8e603 + c324fe6 commit f40d595

2 files changed

Lines changed: 70 additions & 0 deletions

File tree

action.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ inputs:
1717
azure:
1818
description: "Get Azure credentials, exported as ARM_CLIENT_ID and ARM_CLIENT_SECRET"
1919
required: false
20+
azure_tenant_id:
21+
description: "Azure tenant ID. Required if --azure is set"
22+
required: false
23+
azure_subscription_id:
24+
description: "Azure subscription ID. Subscription ID for which your state is stored. Required if --azure is set"
25+
required: false
26+
azure_resource_group:
27+
description: "Azure resource group name. Resource group for which your state is stored. Required if --azure is set"
28+
required: false
2029
azure_no_arm:
2130
description: "Do not export ARM_CLIENT_ID and ARM_CLIENT_SECRET, only TF_VAR_azure_client_id and TF_VAR_azure_client_secret"
2231
required: false

setenv.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
parser.add('--env', required=True, metavar="prod", help='Vault environment eg: prod')
1414
parser.add('--cluster', action='append', metavar="cluster:role:namespace", default=[], help='Can be used multiple times, exported in KUBE_CONFIG_PATH: ~/.kube/atlantis/config')
1515
parser.add('--azure', action='store_true', help='Get Azure credentials, exported as ARM_CLIENT_ID and ARM_CLIENT_SECRET')
16+
parser.add('--azure-tenant-id', help='Azure tenant ID. Required if --azure is set')
17+
parser.add('--azure-subscription-id', help='Azure subscription ID. Subscription ID for which your state is stored. Required if --azure is set')
18+
parser.add('--azure-resource-group', help='Azure resource group name. Resource group for which your state is stored. Required if --azure is set')
1619
parser.add('--azure-no-arm', action='store_true', help='Do not export ARM_CLIENT_ID and ARM_CLIENT_SECRET, only TF_VAR_azure_client_id and TF_VAR_azure_client_secret')
1720
parser.add('--gcp', action='append', metavar="my-project", default=[], help='GCP project names, creates TF_VAR_gcp_project_name for use in "credentials" in google provider')
1821
parser.add('--terraform-registry', action='store_true', help='Get Terraform registry token, expects to be found in vault under "token" in secret/applications/{name}/{env}/terraform-registry')
@@ -170,6 +173,40 @@ def vault_request(path, method='GET', data=None):
170173
response = urllib.request.urlopen(req)
171174
return json.loads(response.read())
172175

176+
def _azure_get_token(tenant_id: str, client_id: str, client_secret: str) -> str:
177+
token_url = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token"
178+
data = urllib.parse.urlencode(
179+
{
180+
"client_id": client_id,
181+
"client_secret": client_secret,
182+
"scope": "https://management.azure.com/.default",
183+
"grant_type": "client_credentials",
184+
}
185+
).encode("utf-8")
186+
req = urllib.request.Request(
187+
token_url,
188+
data=data,
189+
headers={"Content-Type": "application/x-www-form-urlencoded"},
190+
method="POST",
191+
)
192+
with urllib.request.urlopen(req, timeout=10) as resp:
193+
payload = json.load(resp)
194+
return payload["access_token"]
195+
196+
def azure_check_resource_group(tenant_id: str, subscription_id: str, resource_group: str, token: str) -> bool:
197+
url = (
198+
f"https://management.azure.com/subscriptions/{subscription_id}"
199+
f"/resourcegroups/{resource_group}?api-version=2021-04-01"
200+
)
201+
req = urllib.request.Request(url, headers={"Authorization": f"Bearer {token}"})
202+
try:
203+
with urllib.request.urlopen(req, timeout=10):
204+
return True
205+
except urllib.error.HTTPError as exc:
206+
if exc.code in (403, 404):
207+
return False
208+
raise
209+
173210
env_vars = []
174211

175212
# Log in using approle
@@ -269,6 +306,30 @@ def vault_request(path, method='GET', data=None):
269306
("ARM_CLIENT_ID", azure_creds['client_id']),
270307
("ARM_CLIENT_SECRET", azure_creds['client_secret'])
271308
])
309+
310+
tries=0
311+
status("Validating Azure credentials...")
312+
while True:
313+
token = _azure_get_token(
314+
tenant_id=args.azure_tenant_id,
315+
client_id=azure_creds['client_id'],
316+
client_secret=azure_creds['client_secret']
317+
)
318+
if azure_check_resource_group(
319+
tenant_id=args.azure_tenant_id,
320+
subscription_id=args.azure_subscription_id,
321+
resource_group=args.azure_resource_group,
322+
token=token
323+
):
324+
status("Azure credentials are valid and resource group is accessible.")
325+
break
326+
else:
327+
status("Waiting for Azure credentials to propagate...")
328+
tries += 1
329+
if tries >= 6:
330+
status("Azure credentials did not propagate in time, exiting...", True)
331+
break
332+
time.sleep(5)
272333

273334
if args.gcp:
274335
for project in args.gcp:

0 commit comments

Comments
 (0)