@@ -25,6 +25,7 @@ class Route53DNSProvider(DNSProvider):
2525 CERTBOT_PACKAGE = "certbot-dns-route53==5.1.0"
2626 CERTBOT_PROPAGATION_SECONDS = None
2727 AWS_CREDENTIALS_FILE = "~/.aws/credentials"
28+ AWS_CONFIG_FILE = "~/.aws/config"
2829
2930 def __init__ (self ):
3031 super ().__init__ ()
@@ -40,10 +41,6 @@ def __init__(self):
4041 "Install with: pip install boto3"
4142 )
4243
43- # Initialize Route53 client
44- # boto3 automatically uses environment variables:
45- # AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN (optional)
46- # It also supports IAM roles when running on AWS infrastructure
4744 try :
4845 self .client = self .boto3 .client ("route53" )
4946 except Exception as e :
@@ -55,12 +52,14 @@ def __init__(self):
5552 def setup_certbot_credentials (self ) -> bool :
5653 """Setup AWS credentials file for certbot.
5754
58- certbot-dns-route53 uses standard AWS credentials from:
59- 1. Environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
60- 2. ~/.aws/credentials file
61- 3. IAM roles (when running on AWS)
55+ This container will be provided with aws credentials purely for the purpose
56+ of assuming a role. Doing so will enable the boto platform to provision
57+ temporary access key and secret keys on demand!
6258
63- If credentials are in environment variables, we'll create the credentials file.
59+ Using this strategy we can impose least permissive and fast expiring access
60+ to our domain.
61+
62+ Credentials are in environment variables, we'll create the credentials file.
6463 """
6564 aws_access_key = os .getenv ("AWS_ACCESS_KEY_ID" )
6665 aws_secret_key = os .getenv ("AWS_SECRET_ACCESS_KEY" )
@@ -71,31 +70,45 @@ def setup_certbot_credentials(self) -> bool:
7170 return True
7271
7372 credentials_file = os .path .expanduser (self .AWS_CREDENTIALS_FILE )
73+ config_file = os .path .expanduser (self .AWS_CONFIG_FILE )
74+
75+ aws_role_arn = os .getenv ('AWS_ROLE_ARN' )
76+ aws_region = os .getenv ('AWS_REGION' , 'us-east-1' )
77+
7478 credentials_dir = os .path .dirname (credentials_file )
7579
7680 try :
7781 # Create credentials directory
7882 os .makedirs (credentials_dir , exist_ok = True )
7983
80- # Check if credentials file already exists
8184 if os .path .exists (credentials_file ):
8285 print (f"AWS credentials file already exists: { credentials_file } " )
83- return True
8486
85- # Write credentials file in AWS INI format
86- with open (credentials_file , "w" ) as f :
87- f .write ("[default]\n " )
88- f .write (f"aws_access_key_id = { aws_access_key } \n " )
89- f .write (f"aws_secret_access_key = { aws_secret_key } \n " )
87+ else :
88+ # Write credentials file in AWS INI format
89+ with open (credentials_file , "w" ) as f :
90+ f .write ("[certbot-source]\n " )
91+ f .write (f"aws_access_key_id = { aws_access_key } \n " )
92+ f .write (f"aws_secret_access_key = { aws_secret_key } \n " )
93+
94+ # Set secure permissions
95+ os .chmod (credentials_file , 0o600 )
96+ print (f"AWS credentials file created: { credentials_file } " )
9097
91- # Add session token if available
92- aws_session_token = os .getenv ("AWS_SESSION_TOKEN" )
93- if aws_session_token :
94- f .write (f"aws_session_token = { aws_session_token } \n " )
98+ if os .path .exists (credentials_file ):
99+ print (f"AWS config file already exists: { config_file } " )
95100
96- # Set secure permissions
97- os .chmod (credentials_file , 0o600 )
98- print (f"AWS credentials file created: { credentials_file } " )
101+ else :
102+ # Write config file in AWS INI format
103+ with open (config_file , "w" ) as f :
104+ f .write ("[profile certbot]\n " )
105+ f .write (f"role_arn={ aws_role_arn } \n " )
106+ f .write ("source_profile=certbot-source\n " )
107+ f .write (f"region={ aws_region } \n " )
108+
109+ # Set secure permissions
110+ os .chmod (credentials_file , 0o600 )
111+ print (f"AWS config file created: { config_file } " )
99112
100113 # Pre-fetch hosted zone ID if we have a domain
101114 domain = os .getenv ("DOMAIN" )
0 commit comments