--- AWSTemplateFormatVersion: '2010-09-09' Description: 'Continuous Delivery pipeline for static website' Parameters: GitHubOwner: Description: 'The owner of the GitHub repository.' Type: String GitHubOAuthToken: Description: 'The OAuthToken of the GitHub user.' Type: String GitHubRepo: Description: 'The GitHub repository.' Type: String VPC: Description: 'The VPC Id to launch the EC2 instance in.' Type: AWS::EC2::VPC::Id Subnet: Description: 'The Subnet Id to launch the EC2 instance in.' Type: AWS::EC2::Subnet::Id Mappings: RegionMap: 'ap-south-1': AMI: 'ami-cacbbea5' 'eu-west-1': AMI: 'ami-d41d58a7' 'ap-northeast-2': AMI: 'ami-a04297ce' 'ap-northeast-1': AMI: 'ami-1a15c77b' 'sa-east-1': AMI: 'ami-b777e4db' 'ap-southeast-1': AMI: 'ami-7243e611' 'ap-southeast-2': AMI: 'ami-55d4e436' 'eu-central-1': AMI: 'ami-0044b96f' 'us-east-1': AMI: 'ami-c481fad3' 'us-east-2': AMI: 'ami-71ca9114' 'us-west-1': AMI: 'ami-de347abe' 'us-west-2': AMI: 'ami-b04e92d0' Resources: ArtifactStore: Type: "AWS::S3::Bucket" Properties: VersioningConfiguration: Status: Enabled CodePipelineIAMRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - 'codepipeline.amazonaws.com' Action: - 'sts:AssumeRole' Path: '/' Policies: - PolicyName: logs PolicyDocument: Version: '2012-10-17' Statement: - Action: - s3:GetObject - s3:GetObjectVersion - s3:GetBucketVersioning Resource: "*" Effect: Allow - Action: - s3:PutObject Resource: - arn:aws:s3:::codepipeline* - arn:aws:s3:::elasticbeanstalk* Effect: Allow - Action: - codecommit:CancelUploadArchive - codecommit:GetBranch - codecommit:GetCommit - codecommit:GetUploadArchiveStatus - codecommit:UploadArchive Resource: "*" Effect: Allow - Action: - codedeploy:CreateDeployment - codedeploy:GetApplicationRevision - codedeploy:GetDeployment - codedeploy:GetDeploymentConfig - codedeploy:RegisterApplicationRevision Resource: "*" Effect: Allow - Action: - elasticbeanstalk:* - ec2:* - elasticloadbalancing:* - autoscaling:* - cloudwatch:* - s3:* - sns:* - cloudformation:* - rds:* - sqs:* - ecs:* - iam:PassRole Resource: "*" Effect: Allow - Action: - lambda:InvokeFunction - lambda:ListFunctions Resource: "*" Effect: Allow - Action: - opsworks:CreateDeployment - opsworks:DescribeApps - opsworks:DescribeCommands - opsworks:DescribeDeployments - opsworks:DescribeInstances - opsworks:DescribeStacks - opsworks:UpdateApp - opsworks:UpdateStack Resource: "*" Effect: Allow CodePipeline: DependsOn: - EC2Instance Type: "AWS::CodePipeline::Pipeline" Properties: ArtifactStore: Location: !Ref ArtifactStore Type: S3 RoleArn: !Sub '${CodePipelineIAMRole.Arn}' Stages: - Name: Source Actions: - Name: Source ActionTypeId: Category: Source Owner: ThirdParty Version: 1 Provider: GitHub OutputArtifacts: - Name: staticwebsite Configuration: Owner: !Ref GitHubOwner Repo: !Ref GitHubRepo Branch: master OAuthToken: !Ref GitHubOAuthToken - Name: Deploy Actions: - Name: Deploy ActionTypeId: Category: Deploy Owner: AWS Version: 1 Provider: CodeDeploy InputArtifacts: - Name: staticwebsite Configuration: ApplicationName: !Ref Application DeploymentGroupName: !Ref DeploymentGroup - Name: Test Actions: - Name: Test ActionTypeId: Category: Invoke Owner: AWS Version: 1 Provider: Lambda Configuration: FunctionName: !Ref TestLambda UserParameters: !Sub 'http://${EC2Instance.PublicDnsName}' CodeDeployIAMRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - 'codedeploy.amazonaws.com' Action: - 'sts:AssumeRole' Path: '/' ManagedPolicyArns: - 'arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole' Application: Type: "AWS::CodeDeploy::Application" DeploymentGroup: Type: "AWS::CodeDeploy::DeploymentGroup" Properties: ApplicationName: !Ref Application Ec2TagFilters: - Key: DeploymentGroup Type: KEY_AND_VALUE Value: !Ref AWS::StackName ServiceRoleArn: !Sub '${CodeDeployIAMRole.Arn}' SecurityGroup: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: 'static website' VpcId: !Ref VPC SecurityGroupIngress: - FromPort: 80 ToPort: 80 IpProtocol: tcp CidrIp: '0.0.0.0/0' EC2InstanceProfile: Type: 'AWS::IAM::InstanceProfile' Properties: Path: '/' Roles: - !Ref EC2InstanceIAMRole EC2InstanceIAMRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - 'ec2.amazonaws.com' Action: - 'sts:AssumeRole' Path: '/' ManagedPolicyArns: - 'arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforAWSCodeDeploy' EC2Instance: Type: 'AWS::EC2::Instance' Properties: IamInstanceProfile: !Ref EC2InstanceProfile ImageId: !FindInMap [RegionMap, !Ref 'AWS::Region', AMI] InstanceType: 't2.micro' SecurityGroupIds: - !Ref SecurityGroup UserData: 'Fn::Base64': !Sub | #!/bin/bash -x yum update -y && yum install -y ruby wget && wget https://aws-codedeploy-us-east-1.s3.amazonaws.com/latest/install && chmod +x ./install && ./install auto && service codedeploy-agent start /opt/aws/bin/cfn-signal -e $? --region ${AWS::Region} --stack ${AWS::StackName} --resource EC2Instance SubnetId: !Ref Subnet Tags: - Key: DeploymentGroup Value: !Ref AWS::StackName - Key: Name Value: !Ref AWS::StackName CreationPolicy: ResourceSignal: Count: 1 Timeout: PT10M LambdaIAMRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - 'lambda.amazonaws.com' Action: - 'sts:AssumeRole' Path: '/' ManagedPolicyArns: - 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole' Policies: - PolicyName: codepipeline PolicyDocument: Version: '2012-10-17' Statement: - Action: - codepipeline:PutJobFailureResult - codepipeline:PutJobSuccessResult Resource: "*" Effect: Allow TestLambda: Type: "AWS::Lambda::Function" Properties: Code: S3Bucket: 'codepipeline-codedeploy-example-lambda' S3Key: 'v2.zip' FunctionName: 'codepipeline_http_test' Handler: 'index.handler' MemorySize: 128 Role: !Sub '${LambdaIAMRole.Arn}' Runtime: 'nodejs4.3' Timeout: 30 Outputs: URL: Description: 'The URL pointing to the static website.' Value: !Sub 'http://${EC2Instance.PublicDnsName}'