def create_iam_policy(stack, policy_name, actions, groups=[], roles=[], users=[], resources=['*']): """Add IAM policy resource.""" return stack.stack.add_resource( ManagedPolicy( policy_name, ManagedPolicyName=policy_name, Groups=groups, Roles=roles, Users=users, PolicyDocument=Policy( Version='2012-10-17', Statement=[ Statement(Effect=Allow, Action=[ Action('{0}'.format(action.split(':')[0]), '{0}'.format(action.split(':')[1])) for action in actions ], Resource=resources) ])))
def build_policy(self, name, statements, roles, is_managed_policy=False): """ Generate policy for IAM cloudformation template :param name: Name of the policy :param statements: The "rules" the policy should have :param roles: The roles associated with this policy :param is_managed_policy: True if managed policy :return: Ref to new policy """ if is_managed_policy: policy = ManagedPolicy( self.name_strip(name, True), PolicyDocument={ "Version": self.VERSION_IAM, "Statement": statements, }, Roles=roles, Path=self.__role_path, ) else: policy = PolicyType( self.name_strip(name, True), PolicyName=self.name_strip(name, True), PolicyDocument={ "Version": self.VERSION_IAM, "Statement": statements, }, Roles=roles, ) self.__template.add_resource(policy) return policy
def lambda_basepolicy(policyname): with open("policies/lambda_role_base_policy_doc_minimal.json",'r') as f: policydoc = json.load(f) policy = ManagedPolicy(policyname, Description=Join(" ",["Base Policy for all lambda function roles in",Ref(AWS_STACK_NAME)]), PolicyDocument = policydoc) return policy
def createReadOnlyPolicies(self): policies = os.listdir('policies') for policy in policies: with open('policies/' + policy) as data_file: policyData = json.load(data_file) self.template.add_resource( ManagedPolicy(policy.replace('.json', ''), PolicyDocument=policyData))
def create_template(self) -> None: """Create a template from the Blueprint.""" self.template.set_description(self.DESCRIPTION) self.template.set_version("2010-09-09") policy = ManagedPolicy( "Policy", template=self.template, Description=self.DESCRIPTION, ManagedPolicyName=self.POLICY_NAME, PolicyDocument=PolicyDocument( Statement=self.statements, Version="2012-10-17", ), ) self.add_output(policy.title, self.POLICY_NAME) self.add_output(f"{policy.title}Arn", policy.ref())
def generate_policies(ou_path, accounts, role_name): """ Generates the policies for the accounts in the ou_path """ ou_name = ''.join(x.lower().title() for x in ou_path.split('/')) policy_name_prefix = '.'.join(x.lower() for x in ou_path.split('/')) if policy_name_prefix.startswith('.'): policy_name_prefix = policy_name_prefix[1:] policy_name_prefix = '.'.join(x.lower() for x in ou_path.split('/')) if policy_name_prefix.startswith('.'): policy_name_prefix = policy_name_prefix[1:] ou_name = NONALPHANUM.sub('', ou_name) policies = [] if accounts: for account in accounts: account_name = NONALPHANUM.sub('', account['Name']).lower() for role in role_name: res_name = f"{role.lower()}to{account_name}" policy_res = ManagedPolicy( res_name, ManagedPolicyName= f'{policy_name_prefix}.{account_name}-{role}.access', PolicyDocument=switch_policy(account, role, ou_path), Path=r'/SwitchTo/' + role + f'/{account_name}/', Description=f"Allows AssumeRole for role {role} to " "account {account_name} within OU {ou_name}") policies.append(policy_res) for role in role_name: policy_res = ManagedPolicy( f'{role.lower()}to{ou_name.lower()}', ManagedPolicyName=f'{policy_name_prefix}-{role}.access', PolicyDocument=switch_policy(accounts, role, ou_path), Path=r'/switchrole/' + role + r'/', Description= f"Allows AssumeRole for role {role} to all accounts in OU {ou_name}" ) policies.append(policy_res) return policies
def add_managed_policy( c, ManagedPolicyName, PolicyDocument, model, named=False ): cfn_name = scrub_name(ManagedPolicyName) kw_args = { "Description": "Managed Policy " + ManagedPolicyName, "PolicyDocument": PolicyDocument, "Groups": [], "Roles": [], "Users": [] } if named: kw_args["ManagedPolicyName"] = ManagedPolicyName if "description" in model: kw_args["Description"] = model["description"] if "groups" in model: kw_args["Groups"] = parse_imports(c, "policy", model["groups"]) if "users" in model: kw_args["Users"] = parse_imports(c, "user", model["users"]) if "roles" in model: kw_args["Roles"] = parse_imports(c, "role", model["roles"]) if "retain_on_delete" in model: if model["retain_on_delete"] is True: kw_args["DeletionPolicy"] = "Retain" c.template[c.current_account].add_resource(ManagedPolicy( cfn_name, **kw_args )) if c.config['global']['template_outputs'] == "enabled": c.template[c.current_account].add_output([ Output( cfn_name + "PolicyArn", Description=kw_args["Description"] + " Policy Document ARN", Value=Ref(cfn_name), Export=Export(Sub( "${AWS::StackName}-" + cfn_name + "PolicyArn" )) ) ])
def add_figure_lambda(self): ## Now add to a lambda function: function = Function( 'FigLambda', CodeUri='../../protocols', Runtime='python3.6', Handler='log.eventshandler', Description='Lambda Function logging start/stop for NCAP', MemorySize=128, Timeout=90, Role= 'arn:aws:iam::739988523141:role/lambda_dataflow', ## TODO: Create this in template Events={}) figurelamb = self.template.add_resource(function) ## Attach specific permissions to invoke this lambda function as well. cwpermission = Permission('CWPermissions', Action='lambda:InvokeFunction', Principal='events.amazonaws.com', FunctionName=Ref(figurelamb)) self.template.add_resource(cwpermission) ## Because this lambda function gets invoked by an unknown target, we need to take care of its log group separately. figloggroup = LogGroup('FignameLogGroup', LogGroupName=Sub("/aws/lambda/${FigLambda}")) self.template.add_resource(figloggroup) ## Now we need to configure this function as a potential target. ## Initialize role to send events to cloudwatch with open('policies/cloudwatch_events_assume_role_doc.json', 'r') as f: cloudwatchassume_role_doc = json.load(f) ## Now get the actual policy: with open('policies/cloudwatch_events_policy_doc.json', 'r') as f: cloudwatch_policy_doc = json.load(f) cloudwatchpolicy = ManagedPolicy( "CloudwatchBusPolicy", Description=Join(" ", [ "Base Policy for all lambda function roles in", Ref(AWS_STACK_NAME) ]), PolicyDocument=cloudwatch_policy_doc) self.template.add_resource(cloudwatchpolicy) ## create the role: cwrole = Role("CloudWatchBusRole", AssumeRolePolicyDocument=cloudwatchassume_role_doc, ManagedPolicyArns=[Ref(cloudwatchpolicy)]) cwrole_attached = self.template.add_resource(cwrole) self.cwrole = cwrole_attached return figurelamb
def initiate_api_gateway_creation(self): self.template.set_version('2010-09-09') self.template.set_description('Creates a API Gateway which is ' 'used to get data from dynamoDB.') role = self.template.add_resource( Role('RootRole', RoleName="monty-cloud-api-role", Path='/', AssumeRolePolicyDocument={ "Version": "2012-10-17", "Statement": [{ "Action": ["sts:AssumeRole"], "Effect": "Allow", "Principal": { "Service": [ "apigateway.amazonaws.com", "lambda.amazonaws.com", "dynamodb.amazonaws.com" ] } }] })) self.template.add_resource( ManagedPolicy( 'RolePolicies', ManagedPolicyName='api-gw-policy', Description='This policy is used for the DynamoDB table ', PolicyDocument={ "Version": "2012-10-17", "Statement": [{ "Action": ["dynamodb:*", "lambda:*", "s3:*"], "Resource": [ "arn:aws:dynamodb:*:*:table/*", "arn:aws:lambda:*:*:function:*" ], "Effect": "Allow" }] }, Roles=[Ref(role)])) name = self.template.add_resource( RestApi('restApiName', Name='monty-cloud-get-api', Description='Monty Cloud API Gateway', EndpointConfiguration=EndpointConfiguration( Types=['REGIONAL']))) self.template.add_resource( Permission("lambdaApiGatewayInvoke", Action="lambda:InvokeFunction", FunctionName="arn:aws:lambda:{}:{}:function:" "get_data".format(self.region, self.account_number), Principal="apigateway.amazonaws.com", SourceArn="arn:aws:execute-api:{}:{}:*/*" "/GET/get-details".format(self.region, self.account_number))) get_api_resource = self.template.add_resource( Resource('restApiGetDetailsResource', RestApiId=Ref(name), ParentId=GetAtt(name, 'RootResourceId'), PathPart='get-details', DependsOn=name)) get_api_method = self.template.add_resource( Method('restApiGetDetailsMethod', AuthorizationType='None', ApiKeyRequired=False, HttpMethod='GET', ResourceId=Ref(get_api_resource), RestApiId=Ref(name), Integration=Integration(Type='AWS_PROXY', IntegrationHttpMethod='POST', Uri=self.uri.format( self.region, self.region, self.account_number), Credentials=GetAtt(role, "Arn")), MethodResponses=[ MethodResponse( StatusCode='200', ResponseModels={'application/json': 'Empty'}) ], DependsOn=get_api_resource)) deployment = self.template.add_resource( Deployment('restApiDeployment', RestApiId=Ref(name), DependsOn=[get_api_method])) self.template.add_resource( Stage('restApiStage', DeploymentId=Ref(deployment), Description='Prod Stage', MethodSettings=[ MethodSetting(ResourcePath='/get-details', HttpMethod='GET') ], RestApiId=Ref(name), StageName='prod')) return self.template.to_yaml()
managed_policy = ManagedPolicy( "MerchCubeUserPolicy", Description="Specific policy for the merch cube user", Path="/", PolicyDocument=Policy( Version="2012-10-17", Statement=[ Statement( Effect=Allow, Action=[ Action("s3", "DeleteObject"), Action("s3", "GetObject"), Action("s3", "PutObject") ], Resource=[ Join(".", [ "arn:aws:s3:::fanatics", FindInMap("EnvGroupToEnv", Ref(environment_group_param), "name"), "%s/*" % bucket ]) for bucket in bucket_list ], ), Statement(Effect=Allow, Action=[Action("s3", "ListBucket")], Resource=[ Join(".", [ "arn:aws:s3:::fanatics", FindInMap("EnvGroupToEnv", Ref(environment_group_param), "name"), "internal.confidential" ]) ]) ]), Users=[Ref(merch_cube_user)])
from troposphere.iam import ManagedPolicy import boto3 t = Template() t.set_description("Test to create first template using troposphere") t.add_resource( ManagedPolicy("EnriquePolicy", PolicyDocument={ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "cloudformation:Describe*", "cloudformation:List*", "cloudformation:Get*" ], "Resource": "*" }], })) #cfn = boto3.client('cloudformation', region_name='eu-west-1') #response = cfn.create_stack( #StackName="EnriquePolicyCreationTest", #TemplateBody=t.to_json(), #Capabilities=[ #'CAPABILITY_IAM' #],
def global_acm_resources(template, acm_properties): """ Add a function to create a global ACM cert and invoke it for each object in acm_properties. The obejcts in acp_properties should contain the same properties as when creating a normal ACM certificate :type acm_properties list :rtype tuple """ with open(module_path + '/lambda_code/global_acm.py', 'r') as file: acm_code = file.read() write_logs_policy = template.add_resource(ManagedPolicy( "WriteLogsPolicy", Description='Allow Creating Log Groups, Log Streams and putting logs ' 'in it', PolicyDocument={ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:*:*:*" }], }, )) global_acm_function_role = template.add_resource(Role( "GlobalAcmFunctionRole", AssumeRolePolicyDocument={ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" }] }, ManagedPolicyArns=[ Ref(write_logs_policy), 'arn:aws:iam::aws:policy/AWSCertificateManagerFullAccess' ], )) global_acm_function = template.add_resource(Function( "GlobalAcmFunction", Code=Code( ZipFile=acm_code, ), Description=Join('', [Ref(AWS_STACK_NAME), ' query service catalog']), Handler='index.lambda_handler', Role=GetAtt(global_acm_function_role, 'Arn'), Runtime='python2.7', )) output_resources = [] for i, property in enumerate(acm_properties): resource = template.add_resource(CustomResource( "GlobalAcmNr{}".format(i), ServiceToken=GetAtt(global_acm_function, 'Arn'), DomainName=property['DomainName'], DomainValidationOptions=property['DomainValidationOptions'], SubjectAlternativeNames=property['SubjectAlternativeNames'], )) output_resources.append(resource) return tuple(output_resources)
def create_template(self): if self.template_type == 'project_role': template = Template() namespace_param = template.add_parameter( Parameter( "IAMNamespace", Description="Namespace for IAM users, policies, etc.", Type="String", Default="/")) uppercase_env_prefix_param = template.add_parameter( Parameter( "UppercaseAwsEnvironmentPrefix", Description= "Uppercase abbreviation for AWS account (i.e. DEV,QA,PROD)", Type="String")) lowercase_env_prefix_param = template.add_parameter( Parameter( "LowercaseAwsEnvironmentPrefix", Description= "Lowercase abbreviation for AWS account (i.e. dev,qa,prod)", Type="String")) aws_account_number_param = template.add_parameter( Parameter("AccountNumber", Description="AWS Account Number", Type="String")) uppercase_project_name_param = template.add_parameter( Parameter("UppercaseProjectName", Description="Uppercase Project Name", Type="String")) lowercase_project_name_param = template.add_parameter( Parameter("LowercaseProjectName", Description="Lowercase Project Name", Type="String")) pd = PolicyDocument(Version="2012-10-17", Id="Account-Permissions", Statement=self.create_policy_document()) iam_group = template.add_resource( Group( 'IamGroup', #Join('-', [Ref(uppercase_env_prefix_param),Ref(uppercase_project_name_param)]) Path=Ref(namespace_param), GroupName=Join('-', [ Ref(uppercase_env_prefix_param), Ref(uppercase_project_name_param) ]) #'ManagedPolicyArns': ([basestring], False), #Policies'= ([Policy], False) )) iam_managed_policy = template.add_resource( ManagedPolicy("ManagedPolicy", Description=Join('-', [ Ref(uppercase_env_prefix_param), Ref(uppercase_project_name_param), 'project' ]), Groups=[ Join('-', [ Ref(uppercase_env_prefix_param), Ref(uppercase_project_name_param) ]) ], ManagedPolicyName=Join('-', [ Ref(uppercase_env_prefix_param), Ref(uppercase_project_name_param) ]), Path=Ref(namespace_param), PolicyDocument=pd)) if self.debug: print(template.to_json()) with tempfile.NamedTemporaryFile(mode='w', suffix='.rdr', delete=False) as tmp: tmp.write(template.to_json()) self._config.pop('meta-parameters', None) if (not os.path.exists(self.cwd + '/template.json') and not self._config['environment']['template']): with open(self.cwd + '/template.json', 'w') as file: file.write(template.to_json()) file.close() else: if self.debug: print('Not creating template.json') return tmp.name elif self.template_type == 'project_role_jump_account': self._config['parameters'].pop('Resources', None) template = Template() namespace_param = template.add_parameter( Parameter( "IAMNamespace", Description="Namespace for IAM users, policies, etc.", Type="String", Default="/")) uppercase_env_prefix_param = template.add_parameter( Parameter( "UppercaseAwsEnvironmentPrefix", Description= "Uppercase abbreviation for AWS account (i.e. DEV,QA,PROD)", Type="String")) lowercase_env_prefix_param = template.add_parameter( Parameter( "LowercaseAwsEnvironmentPrefix", Description= "Lowercase abbreviation for AWS account (i.e. dev,qa,prod)", Type="String")) aws_account_number_param = template.add_parameter( Parameter("AccountNumber", Description="AWS Account Number", Type="String")) uppercase_project_name_param = template.add_parameter( Parameter("UppercaseProjectName", Description="Uppercase Project Name", Type="String")) lowercase_project_name_param = template.add_parameter( Parameter("LowercaseProjectName", Description="Lowercase Project Name", Type="String")) pd = PolicyDocument(Version="2012-10-17", Statement=self.create_policy_document()) iam_policy = template.add_resource( ManagedPolicy('ManagedPolicy', Description=Join('-', [ Ref(uppercase_env_prefix_param), Ref(uppercase_project_name_param), 'project' ]), PolicyDocument=pd, ManagedPolicyName=Join('-', [ Ref(uppercase_env_prefix_param), Ref(uppercase_project_name_param) ]), Path=Ref(namespace_param))) iam_group = template.add_resource( Group("Group", GroupName=Join('-', [ Ref(uppercase_env_prefix_param), Ref(uppercase_project_name_param) ]))) if self.debug: print(template.to_json()) with tempfile.NamedTemporaryFile(mode='w', suffix='.rdr', delete=False) as tmp: tmp.write(template.to_json()) self._config.pop('meta-parameters', None) if (not os.path.exists(self.cwd + '/template.json') and not self._config['environment']['template']): with open(self.cwd + '/template.json', 'w') as file: file.write(template.to_json()) file.close() else: if self.debug: print('Not creating template.json') if self.debug: print('template file is: ' + str(tmp.name)) return tmp.name else: print('incorrect template type') sys.exit(1)
lambda_managed_policy = template.add_resource( ManagedPolicy( 'LambdaDefaultPolicy', Description='Allows default actions for video-engine lambdas', PolicyDocument={ "Version": "2012-10-17", "Statement": [ { "Action": ["logs:CreateLogStream", "logs:PutLogEvents"], "Resource": "arn:aws:logs:*:*:*", "Effect": "Allow", }, { "Action": ["xray:PutTraceSegments"], "Resource": "*", "Effect": "Allow", }, { "Action": ["dynamodb:PutItem"], "Resource": [GetAtt(video_events_table, 'Arn')], "Effect": "Allow", }, { "Action": ["ssm:GetParameter"], "Resource": ['*'], # Find a way to restrict this "Effect": "Allow", } ], }))
ManagedPolicy( "CommonIamPolicy", Description="Common policy to manage IAM resources", PolicyDocument=Policy( Version="2012-10-17", Statement=[ Statement(Effect=Allow, Action=[ Action("iam", "GetAccountPasswordPolicy"), Action("iam", "ListUsers"), Action("iam", "ListMFADevices"), Action("iam", "ListVirtualMFADEvices") ], Resource=["*"]), Statement(Effect=Allow, Action=[Action("iam", "CreateVirtualMFADevice")], Resource=[ Join("", [ "arn:aws:iam::", Ref("AWS::AccountId"), ":mfa/${aws:username}", ]) ]), Statement(Effect=Allow, Action=[ Action("iam", "ChangePassword"), Action("iam", "CreateAccessKey"), Action("iam", "CreateLoginProfile"), Action("iam", "DeleteAccessKey"), Action("iam", "DeleteLoginProfile"), Action("iam", "EnableMFADevice"), Action("iam", "GetAccessKeyLastUsed"), Action("iam", "GetLoginProfile"), Action("iam", "GetUser"), Action("iam", "ListAccessKeys"), Action("iam", "UpdateAccessKey"), Action("iam", "UpdateLoginProfile") ], Resource=[ Join("", [ "arn:aws:iam::", Ref("AWS::AccountId"), ":user/${aws:username}", ]) ]), Statement( Effect=Deny, NotAction=[ Action("iam", "ChangePassword"), Action("iam", "CreateVirtualMFADevice"), Action("iam", "EnableMFADevice"), Action("iam", "GetUser"), Action("iam", "ListMFADevices"), Action("iam", "ListUsers"), Action("iam", "ListVirtualMFADEvices") ], Resource=["*"], Condition=Condition(Null("aws:MultiFactorAuthAge", "true"), ), ), Statement( Effect=Deny, NotAction=[ Action("iam", "ChangePassword"), Action("iam", "CreateVirtualMFADevice"), Action("iam", "EnableMFADevice"), Action("iam", "GetUser"), Action("iam", "ListMFADevices"), Action("iam", "ListUsers"), Action("iam", "ListVirtualMFADEvices") ], Resource=["*"], Condition=Condition( NumericGreaterThan("aws:MultiFactorAuthAge", "43200")), ), ])))
Value=Ref(email_table), Description="Table Name", )) # Policies allow_db_access_policy = t.add_resource( ManagedPolicy( "AllowDynamoEmailList", Description= "IAM Managed Policy to have full access to DynamoDB Email List Table", ManagedPolicyName="AllowDynamoEmailList", PolicyDocument={ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "dynamodb:PutItem", "dynamodb:DeleteItem", "dynamodb:GetItem", "dynamodb:Scan" ], "Resource": GetAtt(email_table, "Arn") }], })) allow_logs_policy = t.add_resource( ManagedPolicy("AllowFullLogsPolicy", Description="Grants access to logs", ManagedPolicyName="AllowLogAccess", PolicyDocument={
start_media_insights_queue = template.add_resource( Queue('StartMediaInsightsQueue', )) processing_failed_queue = template.add_resource( Queue('ProcessingFailedQueue', )) consume_insights_queue_policy = template.add_resource( ManagedPolicy( 'ConsumeMediaInsightsQueuePolicy', Description='Allows consuming messages from the media-insights queue.', PolicyDocument={ "Version": "2012-10-17", "Statement": [{ "Action": [ "sqs:DeleteMessage", "sqs:ReceiveMessage", "sqs:GetQueueAttributes" ], "Resource": GetAtt(start_media_insights_queue, 'Arn'), "Effect": "Allow", }], })) request_encoding_lambda_role = template.add_resource( Role( 'RequestEncodingLambdaRole', Path="/", AssumeRolePolicyDocument={ "Version":
from troposphere import GetAtt, Output, Ref, Template from troposphere.iam import ManagedPolicy import boto3 t = Template() t.set_description("Test to create first template using troposphere") t.set_version("2012-10-17") t.add_resource( ManagedPolicy("my0cfl0policy", PolicyName="my0cfl0policy", PolicyDocument={ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Resource": ["arn:aws:s3:::my0cfl0bucket"] }], "Roles": "my0cfl0role" })) #print(t.to_yaml()) with open('policy.yaml', 'w') as f: f.write(t.to_yaml())
def add_ecs_execution_role_managed_policy( template: Template, ) -> ManagedPolicy | AWSObject: """ Creates a blanket IAM Managed policy to use for the ECS Execution roles :param troposphere.Template template: :return: The managed policy :rtype: ManagedPolicy """ policy_logical_id = "ECSExecutionRoleCommonRequirements" if policy_logical_id not in template.resources: managed_policy = template.add_resource( ManagedPolicy( policy_logical_id, Description=Sub( r"Managed policy for ECS Execution role in ${STACK_NAME})", STACK_NAME=define_stack_name(), ), Roles=[], PolicyDocument={ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowsForEcrPullFromEcsAgent", "Effect": "Allow", "Action": [ "ecr:GetAuthorizationToken", "ecr:BatchCheckLayerAvailability", "ecr:GetDownloadUrlForLayer", "ecr:GetRepositoryPolicy", "ecr:DescribeRepositories", "ecr:ListImages", "ecr:DescribeImages", "ecr:BatchGetImage", ], "Resource": ["*"], }, { "Sid": "AllowEcsAgentOrientedTasks", "Effect": "Allow", "Action": [ "ecs:DiscoverPollEndpoint", "ecs:Poll", "ecs:Submit*", ], "Resource": ["*"], }, { "Sid": "AllowElbv2Actions", "Effect": "Allow", "Action": [ "elasticloadbalancing:DeregisterInstancesFromLoadBalancer", "elasticloadbalancing:DeregisterTargets", "elasticloadbalancing:Describe*", "elasticloadbalancing:RegisterInstancesWithLoadBalancer", "elasticloadbalancing:RegisterTargets", ], "Resource": ["*"], }, { "Sid": "AllowsEC2Actions", "Effect": "Allow", "Action": [ "ec2:AttachNetworkInterface", "ec2:CreateNetworkInterface", "ec2:CreateNetworkInterfacePermission", "ec2:DeleteNetworkInterface", "ec2:DeleteNetworkInterfacePermission", "ec2:Describe*", "ec2:DetachNetworkInterface", ], "Resource": ["*"], }, ], }, )) return managed_policy else: return template.resources[policy_logical_id]
def main(): '''Function: Generates the Cloudformation template''' template = Template() keyname_param = template.add_parameter( Parameter( 'KeyName', Description='Name of an existing EC2 KeyPair for SSH access', ConstraintDescription='Must be the name of an existing EC2 KeyPair.', Type='AWS::EC2::KeyPair::KeyName', ) ) password_param = template.add_parameter( Parameter( 'PassWord', Type='String', NoEcho=True, MinLength=8, MaxLength=64, Description='Password for the admin account', ConstraintDescription='A complex password at least eight chars long with alphanumeric characters, dashes and underscores.', AllowedPattern="[-_a-zA-Z0-9]*", ) ) template.add_mapping('RegionMap', {'ap-south-1': {'ami': 'ami-ee8ea481'}, 'eu-west-3': {'ami': 'ami-daf040a7'}, 'eu-west-2': {'ami': 'ami-ddb950ba'}, 'eu-west-1': {'ami': 'ami-d2414e38'}, 'ap-northeast-2': {'ami': 'ami-65d86d0b'}, 'ap-northeast-1': {'ami': 'ami-e875a197'}, 'sa-east-1': {'ami': 'ami-ccd48ea0'}, 'ca-central-1': {'ami': 'ami-c3e567a7'}, 'ap-southeast-1': {'ami': 'ami-31e7e44d'}, 'ap-southeast-2': {'ami': 'ami-23c51c41'}, 'eu-central-1': {'ami': 'ami-3c635cd7'}, 'us-east-1': {'ami': 'ami-5cc39523'}, 'us-east-2': {'ami': 'ami-67142d02'}, 'us-west-1': {'ami': 'ami-d7b355b4'}, 'us-west-2': {'ami': 'ami-39c28c41'}}) ec2_security_group = template.add_resource( ec2.SecurityGroup( 'SecurityGroup', GroupDescription='SSH, HTTP/HTTPS open for 0.0.0.0/0', SecurityGroupIngress=[ ec2.SecurityGroupRule( IpProtocol='tcp', FromPort='22', ToPort='22', CidrIp='0.0.0.0/0'), ec2.SecurityGroupRule( IpProtocol='tcp', FromPort='80', ToPort='80', CidrIp='0.0.0.0/0'), ec2.SecurityGroupRule( IpProtocol='tcp', FromPort='443', ToPort='443', CidrIp='0.0.0.0/0'), ], ) ) ec2_role = template.add_resource( Role('EC2Role', AssumeRolePolicyDocument={ "Version" : "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "ec2.amazonaws.com" ] }, "Action": [ "sts:AssumeRole" ] } ] }, ) ) ec2_policy = template.add_resource( ManagedPolicy( 'EC2Policy', PolicyDocument={ "Version": "2012-10-17", "Statement": [ { "Action": "ec2:*", "Resource": "*", "Effect": "Allow" } ] }, Roles=[Ref(ec2_role)] ) ) ec2_profile = template.add_resource( InstanceProfile("EC2InstanceProfile", Roles=[Ref(ec2_role)]) ) ec2_instance = template.add_resource( ec2.Instance( 'Instance', Metadata=Metadata( Init({ "config": InitConfig( files=InitFiles({ "/etc/nginx/conf.d/jenkins.conf": InitFile( content='server { listen 80 default_server; listen [::]:80 default_server; location / { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }', mode="000644", owner="root", group="root" ) }), ) }), ), CreationPolicy=CreationPolicy( ResourceSignal=ResourceSignal(Timeout='PT15M') ), ImageId=FindInMap('RegionMap', Ref('AWS::Region'), 'ami'), InstanceType='t2.micro', IamInstanceProfile=Ref(ec2_profile), KeyName=Ref(keyname_param), SecurityGroups=[Ref(ec2_security_group)], UserData=Base64( Join( '', [ '#!/bin/bash -x\n', 'exec > /tmp/user-data.log 2>&1\n' 'unset UCF_FORCE_CONFFOLD\n', 'export UCF_FORCE_CONFFNEW=YES\n', 'ucf --purge /boot/grub/menu.lst\n', 'export DEBIAN_FRONTEND=noninteractive\n', 'echo "deb http://pkg.jenkins-ci.org/debian binary/" > /etc/apt/sources.list.d/jenkins.list\n', 'wget -q -O jenkins-ci.org.key http://pkg.jenkins-ci.org/debian-stable/jenkins-ci.org.key\n' 'apt-key add jenkins-ci.org.key\n', 'apt-get update\n', 'apt-get -o Dpkg::Options::="--force-confnew" --force-yes -fuy upgrade\n', 'apt-get install -y python-pip\n', 'pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n', 'apt-get install -y nginx\n', 'apt-get install -y openjdk-8-jdk\n', 'apt-get install -y jenkins\n', '# Wait for Jenkins to Set Up\n' "until [ $(curl -o /dev/null --silent --head --write-out '%{http_code}\n' http://localhost:8080) -eq 403 ]; do sleep 1; done\n", 'sleep 10\n', '# Change the password for the admin account\n', "echo 'jenkins.model.Jenkins.instance.securityRealm.createAccount(\"admin\", \"",Ref(password_param),"\")' | java -jar /var/cache/jenkins/war/WEB-INF/jenkins-cli.jar -s \"http://localhost:8080/\" -auth \"admin:$(cat /var/lib/jenkins/secrets/initialAdminPassword)\" groovy =\n", '/usr/local/bin/cfn-init --resource=Instance --region=', Ref('AWS::Region'), ' --stack=', Ref('AWS::StackName'), '\n', 'unlink /etc/nginx/sites-enabled/default\n', 'systemctl reload nginx\n', '/usr/local/bin/cfn-signal -e $? --resource=Instance --region=', Ref('AWS::Region'), ' --stack=', Ref('AWS::StackName'), '\n', ] ) ) ) ) template.add_output([ Output( 'PublicDnsName', Description='PublicDnsName', Value=Join('',['http://', GetAtt(ec2_instance, 'PublicDnsName'),]) ), ]) print(template.to_yaml())