Piszę plik konfiguracyjny Cloudformation, aby utworzyć witrynę internetową za jednym razem. Obejmuje to tworzenie funkcji lambda, tworzenie interfejsu API Gateway, konfigurowanie segmentu S3, tworzenie strefy Route 53 i rekordów.
Jak dotąd:
- Tworzenie funkcji Lambda i jej roli (działa)
- Tworzenie API Gateway to jego wdrożenie i rola (działa)
- Tworzenie segmentu S3 i jego zasad (działa)
- Tworzenie strefy Route 53 i rekordów DNS dla witryny (działa)
- Utwórz domenę dla API Gateway (nie mam pojęcia, co robię)
Więc domain.com
bez problemu obsługuje pliki w segmencie S3. Użycie AWS URI dla API Gateway działa https://trydsoonjc.execute-api.us-west-2.amazonaws.com/app/path/here
bez problemu.
Chcę skonfigurować api.domain.com
punkt API Gateway, aby uzyskać dostęp do interfejsu API serwera.
Jak połączyć Route 53 z API Gateway?
Moja obecna forma chmury jest następująca:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description" : "Website",
"Parameters": {
"DomainName": {
"Type" : "String",
"Description" : "The DNS name of an Amazon Route 53 hosted zone e.g. server.com",
"AllowedPattern" : "(?!-)[a-zA-Z0-9-.]{1,63}(?<!-)",
"ConstraintDescription" : "must be a valid DNS zone name."
}
},
"Mappings" : {
"RegionMap" : {
"us-east-1" : { "S3HostedZoneId" : "Z3AQBSTGFYJSTF", "S3WebsiteEndpoint" : "s3-website-us-east-1.amazonaws.com" },
"us-west-1" : { "S3HostedZoneId" : "Z2F56UZL2M1ACD", "S3WebsiteEndpoint" : "s3-website-us-west-1.amazonaws.com" },
"us-west-2" : { "S3HostedZoneId" : "Z3BJ6K6RIION7M", "S3WebsiteEndpoint" : "s3-website-us-west-2.amazonaws.com" },
"eu-west-1" : { "S3HostedZoneId" : "Z1BKCTXD74EZPE", "S3WebsiteEndpoint" : "s3-website-eu-west-1.amazonaws.com" },
"ap-southeast-1" : { "S3HostedZoneId" : "Z3O0J2DXBE1FTB", "S3WebsiteEndpoint" : "s3-website-ap-southeast-1.amazonaws.com" },
"ap-southeast-2" : { "S3HostedZoneId" : "Z1WCIGYICN2BYD", "S3WebsiteEndpoint" : "s3-website-ap-southeast-2.amazonaws.com" },
"ap-northeast-1" : { "S3HostedZoneId" : "Z2M4EHUR26P7ZW", "S3WebsiteEndpoint" : "s3-website-ap-northeast-1.amazonaws.com" },
"sa-east-1" : { "S3HostedZoneId" : "Z31GFT0UA1I2HV", "S3WebsiteEndpoint" : "s3-website-sa-east-1.amazonaws.com" }
}
},
"Resources": {
"LambdaExecutionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": [ "sts:AssumeRole" ]
}]
},
"Path": "/",
"Policies": [{
"PolicyName": "execution",
"PolicyDocument": {
"Statement": [{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}, {
"Effect": "Allow",
"Action": [
"dynamodb:BatchGetItem",
"dynamodb:CreateTable",
"dynamodb:DeleteItem",
"dynamodb:DescribeTable",
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:UpdateItem",
"s3:GetObject",
"s3:PutObject",
"s3:ListBucket"
],
"Resource": "*"
}]
}
}]
}
},
"APIGatewayExecutionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": [ "sts:AssumeRole" ]
}]
},
"Path": "/",
"Policies": [{
"PolicyName": "execution",
"PolicyDocument": {
"Statement": [{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}, {
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": "*"
}]
}
}]
}
},
"LambdaFunctionUpdate": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"ZipFile": "exports.handler = function (event, context) { context.succeed(\"Hello, World!\"); };"
},
"Description": "Update handler.",
"Handler": "index.handler",
"MemorySize": 128,
"Role": { "Fn::GetAtt": ["LambdaExecutionRole", "Arn" ] },
"Runtime": "nodejs4.3",
"Timeout": 30
}
},
"APIGateway": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Body": @@swagger,
"FailOnWarnings": true,
"Name": "smallPictures",
"Description": "Structured wiki"
}
},
"APITDeploymentTest": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": { "Ref": "APIGateway" },
"Description": "Deploy for testing",
"StageName": "smallPicturesTesting"
}
},
"WebsiteBucket" : {
"Type" : "AWS::S3::Bucket",
"Properties" : {
"BucketName": {"Ref":"DomainName"},
"AccessControl" : "PublicRead",
"WebsiteConfiguration" : {
"IndexDocument" : "index.html",
"ErrorDocument" : "404.html"
}
},
"DeletionPolicy" : "Retain"
},
"WebsiteBucketPolicy" : {
"Type" : "AWS::S3::BucketPolicy",
"Properties" : {
"Bucket" : {"Ref" : "WebsiteBucket"},
"PolicyDocument": {
"Statement": [{
"Action": [ "s3:GetObject" ],
"Effect": "Allow",
"Resource": { "Fn::Join" : ["", ["arn:aws:s3:::", { "Ref" : "WebsiteBucket" } , "/*" ]]},
"Principal": "*"
}]
}
}
},
"DNS": {
"Type": "AWS::Route53::HostedZone",
"Properties": {
"HostedZoneConfig": {
"Comment": { "Fn::Join" : ["", ["Hosted zone for ", { "Ref" : "DomainName" } ]]}
},
"Name": { "Ref" : "DomainName" },
"HostedZoneTags" : [{
"Key": "Application",
"Value": "Blog"
}]
}
},
"DNSRecord": {
"Type": "AWS::Route53::RecordSetGroup",
"Properties": {
"HostedZoneName": {
"Fn::Join": [ "", [ { "Ref": "DomainName" }, "." ]]
},
"Comment": "Zone records.",
"RecordSets": [
{
"Name": { "Ref": "DomainName" },
"Type": "A",
"AliasTarget": {
"HostedZoneId": { "Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "S3HostedZoneId" ]},
"DNSName": { "Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "S3WebsiteEndpoint" ]}
}
}, {
"Name": { "Fn::Join" : ["", ["www.", { "Ref" : "DomainName" }]]},
"Type": "CNAME",
"TTL" : "900",
"ResourceRecords" : [
{"Fn::GetAtt":["WebsiteBucket", "DomainName"]}
]
}
]
}
}
},
"Outputs": {
"WebsiteURL": {
"Value": { "Fn::GetAtt": ["WebsiteBucket", "WebsiteURL" ] },
"Description": "URL for website hosted on S3"
}
}
}
Odpowiedzi:
Musisz utworzyć certyfikat SSL za pomocą Menedżera certyfikatów. Dla krańcowego punktu końcowego utwórz go w eu-east-1, dla regionalnych i prywatnych punktów końcowych utwórz go w regionie, w którym wdrażasz bramę API (lub lambda). Przeczytaj więcej tutaj . Będę odnosić się do ARN jako
CertificateArn
Musisz skonfigurować
AWS::ApiGateway::DomainName
:Umożliwia to domenę dla bramy API. Następnie musisz udostępnić API (tj. Swój RestAPI) na określonym etapie wdrażania . W szablonie nie ma etapów wdrażania. Spójrz
AWS::ApiGateway::Stage
. Minimalny przykład wyglądałby tak:Jednak najprawdopodobniej potrzebujesz w tym dodatkowej konfiguracji. Sugeruję, aby spojrzeć na
MethodSettings
nieruchomości.W końcu wdrożyć mapowania zasobów BasePath:
AWS::ApiGateway::BasePathMapping
. Proponuję zmapować ścieżkę bazową do utworzonego etapu w następujący sposób:Jeśli zmienisz
AWS::ApiGateway::Stage
zasób, musisz wymusić aktualizację odpowiedniegoAWS::ApiGateway::Deployment
zasobu - zwykle oznacza to zmianę nazwyAWS::ApiGateway::Deployment
zasobu, aby o tym pamiętać. W przeciwnym razie nie zostanie wdrożony.Że należy to zrobić.
źródło